背包的伪多时间算法可用于k=2
. 我们能做的最好的就是 sum(S)/2。运行背包算法
for s in S:
for i in 0 to sum(S):
if arr[i] then arr[i+s] = true;
然后查看 sum(S)/2,然后是 sum(S)/2 +/- 1,等等。
对于 'k>=3' 我相信这是 NP 完全的,就像 3 分区问题一样。
对 k>=3 执行此操作的最简单方法就是暴力破解,这是一种方法,不确定它是最快的还是最干净的。
import copy
arr = [1,2,3,4]
def t(k,accum,index):
print accum,k
if index == len(arr):
if(k==0):
return copy.deepcopy(accum);
else:
return [];
element = arr[index];
result = []
for set_i in range(len(accum)):
if k>0:
clone_new = copy.deepcopy(accum);
clone_new[set_i].append([element]);
result.extend( t(k-1,clone_new,index+1) );
for elem_i in range(len(accum[set_i])):
clone_new = copy.deepcopy(accum);
clone_new[set_i][elem_i].append(element)
result.extend( t(k,clone_new,index+1) );
return result
print t(3,[[]],0);
模拟退火可能很好,但由于特定解决方案的“邻居”并不十分清楚,因此遗传算法可能更适合于此。您首先会随机选择一组子集,然后通过在子集之间移动数字来“变异”。