Choose numbers which sum to zero

不打扰是莪最后的温柔 提交于 2020-01-14 04:51:30

问题


There is N number of sets, each containing various number of integers, e.g.:

(-2, -1, 0), (-1,4), (-2, 2, 3), (-3, -2, 4, 6), (-2)

How to pick exactly one number from each set so that these N integers sum to zero? For example:

-1, -1, 2, -2, 4, -2

Note there might be no solution or multiple (in which case it doesn't matter which one I choose).

I was thinking that I can do breath-first search but was wondering if there are any other, preferably faster, ways to solve this.


回答1:


Let dp[i, j] = true iff we can make sum j using one number from each of the sets 1, 2, ..., i.

dp[i, 0] = true for all i
for i = 1 to numSets do
  for num = 1 to sets[i].Count do
    for j = maxSum - sets[i, num] downto -maxSum do
      dp[i, j + sets[i, num]] |= dp[i - 1, j] 

You can use a map to handle negative indexes or add an offset to make them positive. maxSum is the maximum value your sum can take (for example sum of maximums of all sets or sum of absolute values of minimums, whichever is larger). There might be ways to update maxSum as you go as an optimization.

For your example, this will run like so:

(-2, -1, 0), (-1,4), (-2, 2, 3), (-3, -2, 4, 6), (-2)

Iteration over the first set will give dp[1, -2] = dp[1, -1] = dp[1, 0] = true.

Iteration over the second will give dp[2, -3] = true (because dp[2, -2 + -1] |= dp[1, -1] = true), dp[2, -2] = true (because dp[2, -1 + -1] |= dp[1, -1] = true) etc.

If dp[numSets, 0] = true, there is a solution, which you can reconstruct by keeping tracking of which last number you picked for each dp[i, j].

The complexity is O(numSets * K * maxSum), where K is the number of elements of a set. This is pseudopolynomial. It might be fast enough if your values are small. If your values are large but you have few sets with few elements, you are better off bruteforcing it using backtracking.




回答2:


This seems related to the subset sum problem: given a set n integers, is there a subset that sums to 0? That problem is known to be NP-complete and that, in short, means your chances are very small of finding a fast way of doing this.

For one set of integers it's hard enough and in your problem another constraint is added that one integer must be selected from each set. A search algorithm is indeed the way to go but in the worst case you won't be doing much better than an exhaustive search.



来源:https://stackoverflow.com/questions/9754302/choose-numbers-which-sum-to-zero

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!