如何将算法缩小为更小的部分,以便我可以扩展它?

时间:2012-03-05 17:25:09

标签: java algorithm

我已经更新了这个问题(发现最后一个问题不清楚,如果你想参考它,请查看恢复历史记录)。到目前为止目前的答案不起作用,因为我没有清楚地解释我的问题(对不起,第二次尝试)。

目标

尝试采用一组数字(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。

3 个答案:

答案 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