如何计算出2N阵列中两个子阵列的最近和?考虑找到最佳的一个

时间:2012-09-12 00:57:10

标签: arrays algorithm numbers

这是我的问题。

有一个带有2N元素的未排序数组。所有这些元素都是正整数。    问:如何将此数组拆分为两个N数组,两个数组的总和必须彼此最接近

一个直观的想法是,

  1. 将此数组排序为a1< a2< A3< ...< a2N和
  2. 将它们分成两个子阵列a1 a3 a5 ... a(2N-1)和[a2,a4,... a2N], 然后在每个aray中打开两个数字,并保持循环util,我们找到两个数组之间的最小值。
  3. 但是通过这种方式,我们无法确定我们找到了最佳的那个。

2 个答案:

答案 0 :(得分:5)

这是Partition Problem,而且很难(即NP完全)。

那就是说,如果你需要实现这个,那么你建议的贪心算法做得不错。你可以通过确保一个列表并不总是小于另一个列表,从第一个中取2,从第二个中取2,从第一个中取2,......,从第二个取1,来做得更好:

A = [a1, a4, a5, a8, a9, ..., a(n-2), a(n-1)]
B = [a2, a3, a6, a7, ..., a(n-4), a(n-3), an]

这并不总能提供最佳解决方案,但对大多数情况来说,它确实足够好。它也避免了“先走”的偏见。

答案 1 :(得分:2)

你应该查看subset sum problem。在你的情况下,你正在拍摄S / 2的子集和,其中S是全套和。在整数的情况下有一个简单的动态编程算法,这是最着名的。不幸的是,它是伪多项式时间。这意味着运行时间是元素的 size 中的多项式。这使得它在正常意义上成为指数时间,但如果元素不是太大,它就可以正常工作。

子集和动态程序需要稍加修改以强制要求正好N个元素e [i]。如果存在由从1到i中选择的元素组成的子集,并且恰好包含n< = i个元素,则让Q(i,s,n)为真。

然后

Q(i,s,n)= Q(i - 1,s,n)或Q(i - 1,s - e [i],n - 1)

基本情况表明根本不使用任何元素,子集中的总和和所需数字必须都为零,否则Q为假:

Q(0,0,0)= true,否则Q(0,_,_)为假。

要获得答案,请计算Q表(2N,k,N),k =上限(S / 2),上限(S / 2)-1,...直到找到真值。

请注意,此问题足够接近子集总和以使其难以实现NP。这意味着真正的多项式时间算法(如排序方案)将是最优性的近似值。当然,这对于现实目的来说可能还不错。