我正在构建一种算法,该算法在给定步骤S的n个序列(可以是正实数)的重复下进行排列,在所有组合的总和为k的约束下,ka为正整数。
因此我的问题是找到等式的解决方案:
x 1 + x 2 +⋯+ x n = k 其中
0≤xi≤bi 和S(步骤)一个有限小数的实数。
例如,如果0≤xi≤50,S = 2.5则xi = {0,2.5,5,...,47.5,50}。
这里的观点是仅通过具有和= k的组合来查看,因为如果n很大则不可能生成所有排列,因此我想绕过它以仅生成与约束匹配的组合。
我想从n = 2开始,并找到与约束匹配的所有线性组合。
例如:如果xi = {0,2.5,5,...,47.5,50}和k = 100,那么我们只有一个组合= {50,50} 对于n = 3,我们得到n = 2乘3的组合,即{50,50,0},{50,0,50}和{0,50,50}加上组合{50,47.5,2.5} * 3!等...
如果xi = {0,2.5,5,...,37.5,40}和k = 100,那么我们有n = 2的0个组合,因为2 * 40 <100,我们有{40,40, n = 3的20}次3 ...(如果我没记错的话)
我有点迷失,因为我似乎找不到合适的方法来启动算法,知道我应该将步骤S和b作为输入。
你有什么建议吗?
由于
答案 0 :(得分:2)
您可以通过将所有内容除以 S 将您的问题转换为整数问题:我们想找到所有整数序列 y 1 ,...,y n with:
(1)0≤y i ≤⌊b/S⌋
(2) y 1 + ... + y n = k / S
如果 k 不是 S 的倍数,我们可以看到没有解决方案。一旦我们减少了问题,我建议使用伪多项式动态编程算法来解决subset sum problem,然后从中重构解决方案。设 f(i,j)是与 i 元素进行求和 j 的方法的数量。我们有以下重复:
f(0,0) = 1
f(0,j) = 0 forall j > 0
f(i,j) = sum_{m = 0}^{min(floor(b / S), j)} f(i - 1, j - m)
我们可以通过逐行填写 O(n * k / S)时间来解决 f 。现在我们想要重建解决方案。我使用Python风格的伪代码来说明这个概念:
def reconstruct(i, j):
if f(i,j) == 0:
return
if i == 0:
yield []
return
for m := 0 to min(floor(b / S), j):
for rest in reconstruct(i - 1, j - m):
yield [m] + rest
result = reconstruct(n, k / S)
result
将列出所有可能的组合。
答案 1 :(得分:0)
您所描述的内容听起来像subset sum problem的特例。一旦你用这些术语表达,你会发现Pisinger显然有linear time algorithm来解决你问题的更一般版本,因为你的权重有限。如果您对设计自己的算法感兴趣,可以先阅读Pisinger's thesis来获得一些想法。
由于您正在寻找所有可能的解决方案,而不仅仅是一个解决方案,动态编程方法可能是您最好的选择。