Arrays 两个数组的最大子集和
我甚至不确定这是否可以在多项式时间内完成 问题: 给定两个实数数组Arrays 两个数组的最大子集和,arrays,algorithm,math,subset-sum,Arrays,Algorithm,Math,Subset Sum,我甚至不确定这是否可以在多项式时间内完成 问题: 给定两个实数数组 A = (a[1], a[2], ..., a[n]), B = (b[1], b[2], ..., b[n]), (b[j] > 0, j = 1, 2, ..., n) 和一个数字k,找到a(a'=(a[i(1)]的子集a', a[i(2)],…,a[i(k)],它精确地包含k元素,使得(和a[i(j)]/(和b[i(j)]最大化,其中j=1,2,…,k 例如,如果k==3,并且{a[1],a[5],a[7]}是
A = (a[1], a[2], ..., a[n]),
B = (b[1], b[2], ..., b[n]), (b[j] > 0, j = 1, 2, ..., n)
和一个数字k
,找到a(a'=(a[i(1)]的子集a'
,
a[i(2)],…,a[i(k)]
,它精确地包含k
元素,使得(和a[i(j)]/(和b[i(j)]
最大化,其中j=1,2,…,k
例如,如果k==3
,并且{a[1],a[5],a[7]}
是结果,则
(a[1] + a[5] + a[7])/(b[1] + b[5] + b[7])
应大于任何其他组合。有什么线索吗?假设
B
的条目是肯定的(听起来这个特例可能对您有用),那么就有一个O(n^2 log n)
算法
让我们首先解决一个问题,即对于特定的t
,是否存在这样的解决方案
(sum a[i(j)])/(sum b[i(j)]) >= t.
清除分母后,此条件等于
sum (a[i(j)] - t*b[i(j)]) >= 0.
我们所要做的就是选择a[i(j)]-t*b[i(j)]
的k
最大值
现在,为了解决
t
未知时的问题,我们使用了一种动力学算法。将t
视为一个时间变量;我们感兴趣的是一维物理系统的演化,其中n
粒子具有初始位置a
和速度-B
。每个粒子最多一次与其他粒子交叉,因此事件数为O(n^2)
。在交叉点之间,sum(a[i(j)]-t*b[i(j)]
的最佳值线性变化,因为k
的相同子集是最佳的。如果b可以包含负数,那么这是NP难的
由于该问题的NP难度:
给定k和数组B,B的大小k有一个子集和为零
在这种情况下,A变得无关紧要
当然,从你的评论来看,B似乎必须包含正数。我猜这是NP难问题,99.99%的几率是这样,但我能问一下你在哪里看到这个问题吗?总之,这个问题很好。谢谢你的回答。我将一个真正的负载平衡问题简化为这个抽象版本。我在这个问题上花了两天多的时间。现在,我也有一种感觉,它是NP难的。有
n
choosek
可能的比率,因此设置了复杂性的上限。我正在考虑一种方法,从a[I]/b[I]
开始选择最大的比率,然后选择使k=2
案例尽可能大的索引。这样,您就必须在该步骤上比较n-1
比率。然后继续选择第三个索引。一旦你选择了k
指数,证明这一点总是能给出最佳比率可能很难(或者可能不是真的!),但尝试证明可能会提供一些见解。嗨,约翰,非常感谢你的回答。昨天我试着证明你的算法的正确性,但最后得到了一个反例。检查A=[10,2,1,0.2],B=[7,3,2,1.34]和k=3。A[i]和B[i]是零还是负?我怀疑有一种O(n^2)
算法,它使用线的排列和已经开发的计算几何机制来处理它们。+1极好的答案。我从没见过这样的事。我很好奇,这种方法是否可以应用于更大的一类问题,以及这种类型的解决方案叫什么……或者你是从稀薄的空气中提取出来的?@JohnPS动力学算法是计算几何学家青睐的一种设计技术。当你有一个连续的参数(解释为时间)和一个“物理系统”时,它们是适用的,除了在有限的时间内变化外,变化很好。嗨!谢谢你的回复。对不起,我忘了提到B只包含正数。