Optimization 算法-找到两个数组之和之间的最小减法

Optimization 算法-找到两个数组之和之间的最小减法,optimization,language-agnostic,Optimization,Language Agnostic,我现在正在找工作,做很多算法练习。我的问题是: 给定两个数组:长度相同的a和b,主题是通过在a和b之间交换元素,使| sum(a)-sum(b)|最小 以下是我的想法: 假设我们交换a[i]和b[j],设置Delt=sum(a)-sum(b),x=a[i]-b[j] 然后Delt2=sum(a)-a[i]+b[j]-(sum(b)-b[j]+a[i])=Delt-2*x, 然后变化=|Delt |-| Delt2 |,与| Delt | ^2-| Delt2 | ^2=4*x*(Delt-x

我现在正在找工作,做很多算法练习。我的问题是:


给定两个数组:长度相同的a和b,主题是通过在a和b之间交换元素,使| sum(a)-sum(b)|最小


以下是我的想法:

假设我们交换a[i]和b[j],设置Delt=sum(a)-sum(b),x=a[i]-b[j]
然后Delt2=sum(a)-a[i]+b[j]-(sum(b)-b[j]+a[i])=Delt-2*x,
然后变化=|Delt |-| Delt2 |,与| Delt | ^2-| Delt2 | ^2=4*x*(Delt-x)成比例

基于上述思想,我得到了以下代码:




然而,有谁有更好的解决方案吗?如果你得到了,请告诉我,我将非常感谢你

这个问题基本上是一个带有额外相等部分约束的优化问题。我将证明,添加此约束并不会使问题变得更容易

证明:
假设有一个算法
A
在多项式时间内解决了这个问题,我们可以在多项式时间内解决这个问题

Partition(S):
for i in range(|S|):
   S += {0}
   result <- A(S\2,S\2) //arbitrary split S into 2 parts
   if result is a partition: //simple to check, since partition is NP.
     return true.
return false //no partition
分区:
对于范围内的i(| S |):
S+={0}

结果S+(0,0,…,0)
[k乘以0],可以通过还原直接证明NP硬度。多项式是平凡的,正确性与上述部分的正确性证明非常相似:[如果有一个分区,添加“平衡”零是可能的;另一个方向是简单地修剪这些零]

只是一个注释。通过所有这些交换,您基本上可以根据需要排列两个数组的内容。因此,值在哪个数组中开始并不重要


我脑子里想不出来,但我确信有一个建设性的解决方案。我想如果你先把它们分类,然后按照某种规则处理它们。如果值为0,如果和(a)>和(b),那么将a的其他元素插入到b中

您的问题相当于“给定一个长度为2*n且和(a)=2*S的数组a,在数组中精确地找到n个元素,其总数尽可能接近S。”这看起来像是伪装的背包问题。@n.m.更像马克提到的分区问题。。。但是还有一个额外的限制:相同数量的元素…@amit:我不确定它是如何像分区问题一样,具有相同数量的元素约束。我看到的是“从每对元素中只取一个元素”约束,而不是“只取所有元素的一半”约束。这两者可能是等价的,但可能是以某种非平凡的方式。@amit:Oops,我还没有意识到允许在不同的位置交换元素。这确实是一个不同的问题。如果TS自己发明了这个问题,那就这样吧;如果不是,我猜问题作者的意图是只允许在同一位置交换元素。这样做更自然。我相信你的缩进搞错了-你为什么要执行
result@jpalecek:我每一步执行
A(s/2,s/2)
一次,然后用
k
零的数量检查可能的解决方案,其中
k
是迭代的数量。这里我并没有使用约简,我在证明,如果存在这样一个算法,P=NP,这相当于说这个算法是NP难的。[因为它显然是NP,如果P=NP,那么P=NP=NP完全]问题是,你必须用一个约化来证明NP硬度,因为NP硬度是根据约化定义的。你已经证明了P^A中的分区是NP完全的,但这并不意味着(至少不是直接的)A是NP完全的。此外,如果你只是把所有的零加起来,问一次A,也会有效,你会得到一个减少。@jpalecek:我编辑了答案,并添加了你建议的减少。我几乎可以肯定有一个定理,如果对于某个问题:多项式解->P=NP,那么这个问题是NP难的[虽然我记不起是哪个定理,所以我可能是错的]。无论如何,我很感谢你的评论,你建议的降价方法要简单得多。@jpalacek:我不认为阿米特的降价有什么问题(尽管你的降价方法肯定更简单)。根据Wikipedia页面,一个NP完全问题(如划分)到目标问题的多项式时间图灵可约性足以证明目标问题是NP难的。图灵可约性允许对目标问题进行多项式次数的调用。对于NP完备性,只需要多个一次约简(最终只允许对目标问题进行一次调用)。
Partition(S):
for i in range(|S|):
   S += {0}
   result <- A(S\2,S\2) //arbitrary split S into 2 parts
   if result is a partition: //simple to check, since partition is NP.
     return true.
return false //no partition