I am trying to solve this popular problem:
"Given an integer array, divide the array into two subsets, A and B, while respecting the following conditions.
the intersection of A and B is null.
the union A and B is equal to the original array.
the number of elements in subset A is minimal.
the sum of A's elements is greater than the sum of B's elements.
Return the subset A in increasing order, where the sum of A's elements is greater than the sum of B's elements. If more than one subset exists, return the one with the maximal sum."
I found several solutions online but none of them solve it when the test case is [2,2,2,5]
I wrote the following code:
def subsetA(nums):
nums.sort(reverse=True)
subset_a = []
sum_a = 0
sum_b = 0
for num in nums:
if sum_a <= sum_b:
sum_a += num
subset_a.append(num)
else:
sum_b += num
return sorted(subset_a)
This solution works for a lot of cases but it doesn't work for the test case I mentioned above.
The answer should be [2,2,2]. But i cannot think of any solution that will return that answer.
How can I improve this code?
One way to solve this is as a linear program with binary variables. Suppose the array is held by the variable arr, where arri is the value of the element at index
i.First define the binary variables.
xi equals 1 if arri is assigned to A, and equals 0 if it is assigned to B
The objective (function) and constraints are as follows::
min ∑ixi
subject to:
∑iarrixi >= ∑iarri(1-xi) + t
t is a pre-defined tolerance to ensure that a strict inequality is achieved (linear programs cannot have strict inequalities).
Notice that 1-xi equals 1 if arri is assigned to B.
The constraint needs to be rearranged as follows.
∑iarrixi >= (∑iarri + t)/2
An integer linear programming (ILP) package can then be used to obtain optimal values for the variables.