Algorithm - find the minimum subtraction between the sum of two arrays

Now I am looking for work and performing many algorithms. Here is my problem:


Given two arrays: a and b with the same length, the subject must do | sum (a) -sum (b) | minimal by replacing elements between a and b.


Here is mine, though:

suppose we change a [i] and b [j], put Delt = sum (a) - sum (b), x = a [i] -b [j]
then Delt2 = sum (a) -a [i] + b [j] - (sum (b) -b [j] + a [i]) = Delt - 2 * x,
then change = | Delt | - | Delt2 |, which is proportional to | Delt | ^ 2 - | Delt2 | ^ 2 = 4 * x * (Delt-x),

Based on the thought above, I got the following code:


Delt = sum(a) - sum(b); done = false; while(!done) { done = true; for i = [0, n) { for j = [0,n) { x = a[i]-b[j]; change = x*(Delt-x); if(change >0) { swap(a[i], b[j]); Delt = Delt - 2*x; done = false; } } } } 

However, does anyone have a much better solution? If you have, tell me, and I will be very grateful to you!

+6
source share
2 answers

This problem is mainly related to the Partition Problem optimization problem with the additional restriction of equal parts. I will prove that adding this constraint does not make the task easier.

NP-Hardness proof: Suppose that there is an algorithm A that solves this problem in polynomial time, we can solve Partition-Problem in polynomial time.

 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 

Correctness:
If there is a section denoted as (S1, S2) [it is assumed that S2 has more elements], at the iteration | S2 | - | S1 | [Those. when adding | S2 | - | S1 | zeros]. The entrance to A will contain enough zeros, so we can return two arrays of equal length: S2, S1 + {0,0, ..., 0}, which will be a partition on S , and the algorithm will give true,
If the algorithm gives true and iteration k , we had two arrays: S2, S1, with the same number of elements and equal values. removing k zeros from arrays, we get a partition with the original S, so S has a partition.

polynomial: Suppose A takes time P(n) , the algorithm we created will take time n*P(n) , which is also a polynomial.

Conclusion:
If this problem is solvable in polynomial time, then the Partion problem, and, therefore, P = NP. based on this: this problem is NP-Hard.

Since this problem is NP-Hard, you probably need an exponential algorithm for an exact solution. One of them is simple backtracking [I leave it as a reading exercise to implement a backtracking solution)

EDIT : as @jpalecek mentioned: simply by creating the abbreviation: S->S+(0,0,...,0) [k times 0], one can directly prove NP-hardness by reduction. the polynomial is trivial, and the correctness is very similar to the likelihood proof described above: [if there is a section, adding “balancing” zeros is possible; another direction just trims those zeros]

+3
source

Just a comment. Thanks to this replacement, you can arrange the contents of both arrays as you wish. Therefore, no matter in which array the values ​​begin.

I can’t do it in my head, but I’m sure that there is a constructive solution. I think if you sort them first and then process them according to some rule. Something along the lines If value > 0 and if sum(a)>sum(b) then insert to a else into b

0
source

Source: https://habr.com/ru/post/898477/


All Articles