2017-02-16 4 views
-1

здесь у меня есть массив чисел, как определить, можно ли разделить массив на два подмножества, для которых сумма элементов в обоих подмножествах одинакова, если подмножества доступны, программа должна return true.Подмножества, имеющие одинаковый сумма-питон

For array = [8, 6, 3, 5], the output should be sub(array) = true 

Можно разделить этот массив на два подмножества, которые имеют сумму 8: [8] и [3,5].

`

+3

вы смотрели на https: // эн. wikipedia.org/wiki/Subset_sum_problem Ваш вопрос является более продвинутой проблемой, которая требует некоторого причудливого динамического программирования, я сомневаюсь, что есть библиотека python, которая может сделать это за вас :( – jcr

+0

Okay спасибо ...... – yzcop

+0

http://stackoverflow.com/questions/6012963/subset-sum-problem; http://stackoverflow.com/questions/23087820/python-subset-sum –

ответ

1

Вот перебором решение. Он использует рецепт poweret от Itertools Recipes в документах для создания всех подмножеств. Затем он сортирует и группирует их по сумме, используя itertools.groupby. Затем, наконец, он проверяет все пары подмножеств с одинаковой суммой, чтобы найти пары, которые не пересекаются.

from itertools import chain, combinations, groupby 

def equal_sum_partitions(seq): 
    subsets = chain.from_iterable(combinations(seq, r) for r in range(len(seq)+1)) 
    for k, g in groupby(sorted(subsets, key=sum), key=sum): 
     group = [set(u) for u in g] 
     if len(group) > 1: 
      for u, v in combinations(group, 2): 
       if not u & v: 
        print(k, (u, v)) 

# test 

equal_sum_partitions([2, 4, 8, 6, 3, 5]) 

выход

5 ({5}, {2, 3}) 
6 ({6}, {2, 4}) 
7 ({2, 5}, {3, 4}) 
8 ({8}, {2, 6}) 
8 ({8}, {3, 5}) 
8 ({2, 6}, {3, 5}) 
9 ({4, 5}, {3, 6}) 
10 ({8, 2}, {4, 6}) 
10 ({4, 6}, {2, 3, 5}) 
11 ({8, 3}, {5, 6}) 
11 ({8, 3}, {2, 4, 5}) 
13 ({8, 5}, {3, 4, 6}) 
14 ({8, 6}, {2, 3, 4, 5}) 
14 ({8, 2, 4}, {3, 5, 6}) 
+1

Что делать, если входной массив имеет дублированный элемент? например '[8, 8, 2, 1, 3]' Есть два подмножества суммы 11, но этот метод их не захватывает. – asongtoruin

+0

@asongtoruin Правда, но я решил предположить, что мы работаем с истинными наборами, которые не содержат дубликатов. ;) Если исходный набор содержит два '' '' '' '' '' '' '' '' {{8}, {8}) 'count как действительный раздел? –

+0

Отличное использование itertools. Но так сложно, после того, как у вас есть подмножества, вы можете просто перебирать их и проверять 'if sum (sub) == sum (seq)/2' Вот и все. – JanHak

0

Я нашел решение, но он поднимет ошибку памяти для больших входов :(

def subs(l): 
if l == []: 
    return [[]] 
x = subs(l[1:]) 
return x + [[l[0]] + y for y in x] 

def sub(arr): 
ls=[] 
ls=subs(arr) 
for i in ls: 
    if(sum(list(set(arr)-set(i)))==sum(i)): 
     return True 
return False 
Смежные вопросы