我已经更新了这个问题(发现最后一个问题不清楚,如果你想参考它,请查看恢复历史记录)。到目前为止目前的答案不起作用,因为我没有清楚地解释我的问题(对不起,第二次尝试)。
目标:
尝试采用一组数字(pos或neg,因此需要限制来限制特定变量的增长)并找到可用于获得特定总和的线性组合。例如,要使用[2,4,5]得到10的总和,我们得到:
5*2 + 0*4 + 0*5 = 10
3*2 + 1*4 + 0*5 = 10
1*2 + 2*4 + 0*5 = 10
0*2 + 0*4 + 2*5 = 10
如何创建可扩展用于大量变量和target_sums的算法?如果给出一个算法,我可以自己编写代码,但如果有一个库可用,我对任何库都很好,但更喜欢使用java。
答案 0 :(得分:2)
一旦你将T[z][i]
设置为true
,一个想法就是摆脱循环,因为你基本上只在这里修改T[z][i]
,如果它变成了true
},它不会再被修改。
for i = 1 to k
for z = 0 to sum:
for j = z-x_i to 0:
if(T[j][i-1]):
T[z][i]=true;
break;
EDIT2:此外,如果我做对了,T[z][i]
取决于数组T[z-x_i..0][i-1]
。 T[z+1][i]
取决于T[z+1-x_i..0][i-1]
。因此,一旦您知道T[z][i]
是否为true
,您只需要检查一个额外元素(T[z+1-x_i][i-1]
)即可知道T[z+1][i-1]
是否为true
。
假设您代表T[z][i]
是否由变量changed
更新的事实。然后,您可以简单地说T[z][i] = changed && T[z-1][i]
。所以你应该在两个循环而不是三个循环中完成。这应该会更快。
现在,要扩展它 - 现在T[z,i]
仅取决于T[z-1,i]
和T[z-1-x_i,i-1]
,因此要填充T[z,i]
,您无需等到整个(i-1)
填充{1}}列。只要填充了所需的值,您就可以开始T[z,i]
。我不知道细节就无法实现它,但你可以尝试这种方法。
答案 1 :(得分:0)
我认为这就像无边背包?您可以完全省略c
上的循环。
for i = 1 to k
for z = 0 to sum
T[z][i] = z >= x_i cand (T[z - x_i][i - 1] or T[z - x_i][i])
答案 2 :(得分:0)
根据您给出的原始示例数据(术语的线性组合)和您在评论部分中对我的问题的回答(有界限),蛮力方法是否会起作用?
c0x0 + c1x1 + c2x2 +...+ cnxn = SUM
我猜我错过了一些重要的东西,但无论如何它仍然存在:
蛮力分而治之:
多处理的伪代码
class Controller
work_queue = Queue
solution_queue = Queue
solution_sets = []
create x number of workers with access to work_queue and solution_queue
#say for 2000 terms:
for partial_set in coefficient_generator(start_term=0, end_term=999):
if worker_available(): #generate just in time
push partial set onto work_queue
while solution_queue:
add any solutions to solution_sets
#there is an efficient way to do this type of polling but I forget
class Worker
while true: #actually stops when a stop work token is received
get partial_set from the work queue
for remaining_set in coefficient_generator(start_term=1000, end_term=1999):
combine the two sets (partial_set.extend(remaining_set))
if is_solution(full_set):
push full_set onto the solution queue