Balance two lists until their sums are equal and with minimal swaps in two lists in Python

a = [70, 30, 33, 23, 4, 4, 34, 95]
b = [50, 10, 10, 7]

I have tried this, but I know that this is not accurate enough

if sum(a) > sum(b):
   a.sort()
   b.sort()
   temp = [int(i) for i in a]
   i=0
   while(sum(b) <= sum(temp)  and (i <= len(a) - 1)):
      b.append(a[i])
      temp.remove(a[i])
      i = i+1

    a = [int(i) for i in temp]
if sum(b) > sum(a):
    a.sort()
    b.sort()
    temp = [int(i) for i in b]
    i=0
    while(sum(a) <= sum(temp)  and (i <= len(b) - 1)):
        a.append(b[i])
        temp.remove(b[i])
        i = i+1        

    b = [int(i) for i in temp]

Result:

sums = 186, 184

lists = [7, 10, 70, 95, 4], [4, 10, 23, 30, 33, 34, 50]

Required Answer:

sums = 185, 185

lists = [7, 10, 23, 50, 95], [4, 4, 10, 30, 33, 34, 70]

+4
source share
3 answers

a b, b a. , , . 12 , 2**12 == 4096. , .

0

, , , , .

, , :

from itertools import chain, combinations

def powerset(iterable):
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

def lst_difference(lst, other):
    s = list(lst)
    for el in other:
        s.remove(el)
    return s

a = [70, 30, 33, 23, 4, 4, 34, 95]
b = [50, 10, 10, 7]

lst = a + b
total = sum(lst)

for subset in powerset(lst):
    if sum(subset) == total // 2:
        other_subset = lst_difference(lst, subset)

        print('subset1 = {}, subset2 = {}'.format(subset, other_subset))

:

subset1 = (70, 95, 10, 10), subset2 = [30, 33, 23, 4, 4, 34, 50, 7]
subset1 = (30, 95, 50, 10), subset2 = [70, 33, 23, 4, 4, 34, 10, 7]
subset1 = (30, 95, 50, 10), subset2 = [70, 33, 23, 4, 4, 34, 10, 7]
subset1 = (33, 23, 34, 95), subset2 = [70, 30, 4, 4, 50, 10, 10, 7]
subset1 = (33, 95, 50, 7), subset2 = [70, 30, 23, 4, 4, 34, 10, 10]
subset1 = (30, 33, 23, 4, 95), subset2 = [70, 4, 34, 50, 10, 10, 7]
subset1 = (30, 33, 23, 4, 95), subset2 = [70, 4, 34, 50, 10, 10, 7]
subset1 = (23, 95, 50, 10, 7), subset2 = [70, 30, 33, 4, 4, 34, 10]
subset1 = (23, 95, 50, 10, 7), subset2 = [70, 30, 33, 4, 4, 34, 10]
subset1 = (70, 23, 4, 4, 34, 50), subset2 = [30, 33, 95, 10, 10, 7]
subset1 = (30, 33, 95, 10, 10, 7), subset2 = [70, 23, 4, 4, 34, 50]
subset1 = (70, 30, 33, 4, 4, 34, 10), subset2 = [23, 95, 50, 10, 7]
subset1 = (70, 30, 33, 4, 4, 34, 10), subset2 = [23, 95, 50, 10, 7]
subset1 = (70, 4, 34, 50, 10, 10, 7), subset2 = [30, 33, 23, 4, 95]
subset1 = (70, 4, 34, 50, 10, 10, 7), subset2 = [30, 33, 23, 4, 95]
subset1 = (70, 30, 23, 4, 4, 34, 10, 10), subset2 = [33, 95, 50, 7]
subset1 = (70, 30, 4, 4, 50, 10, 10, 7), subset2 = [33, 23, 34, 95]
subset1 = (70, 33, 23, 4, 4, 34, 10, 7), subset2 = [30, 95, 50, 10]
subset1 = (70, 33, 23, 4, 4, 34, 10, 7), subset2 = [30, 95, 50, 10]
subset1 = (30, 33, 23, 4, 4, 34, 50, 7), subset2 = [70, 95, 10, 10]
0

, . , , , . , :

from itertools import combinations
from collections import Counter

a = [70, 30, 33, 23, 4, 4, 34, 95]
b = [50, 10, 10, 7]

def balance(small, big):
    small.sort()
    big.sort()
    diff = sum(big) - sum(small)
    if diff < 0:
        small, big = big, small
    stack = {(0, 1)}  # each element is (# of elements to take from small, # of elements to take from big)
    while stack:
        i, j = sorted(stack, key=lambda t: t[0]+t[1]).pop(0)
        stack.remove((i, j))
        diff = sum(big) - sum(small)
        if i is 0:
            matches = [(Counter(), Counter(x)) for x in combinations(big, j) if diff - 2 * sum(x) is 0]
        else:
            matches = [(Counter(x), Counter(y)) for x in combinations(small, i) for y in combinations(big, j) if
                       diff - 2 * sum(y) + 2 * sum(x) is 0]
        if matches:
            return list((Counter(small) - matches[0][0] + matches[0][1]).elements()), \
                   list((Counter(big) - matches[0][1] + matches[0][0]).elements())
        else:
            if sum(big[-j:]) * 2 - sum(small[-i:]) > diff and i + 1 < len(small):
                stack.add((i + 1, j))
            if sum(big[:j]) * 2 - sum(small[:i]) < diff and j + 1 < len(big):
                stack.add((i, j + 1))

balance(a, b) ([7, 10, 50, 23, 95], [4, 4, 30, 33, 34, 70, 10])

0
source

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


All Articles