-1

here i have an array of numbers, how to determine whether array can be divided into two subsets for which the sum of elements in both subsets is the same, if the subsets are available, the program should return true.

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

It is possible to partition this array into two subsets that have a sum of 8: [8] and [3,5].

`

yzcop
  • 21
  • 4
  • 3
    have you looked at https://en.wikipedia.org/wiki/Subset_sum_problem your question is a more advance problem that requires some fancy dynamic programming, I doubt there is a python library that can do it for you :( – jcr Feb 16 '17 at 10:22
  • http://stackoverflow.com/questions/6012963/subset-sum-problem ; http://stackoverflow.com/questions/23087820/python-subset-sum – Chris_Rands Feb 16 '17 at 10:32
  • I noticed I was voted down, could whoever do it provide a reason? – yzcop Feb 16 '17 at 11:21
  • I certainly didn't down-vote, but it's quite common for questions to get down-voted when they don't include some code that attempts to solve the problem. – PM 2Ring Feb 16 '17 at 11:26

2 Answers2

2

Here's a brute-force solution. It uses the powerset recipe from the Itertools Recipes in the docs to generate all the subsets. It then sorts and groups them by sum, using itertools.groupby. Then finally it checks all pairs of subsets with the same sum to find pairs that do not intersect.

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])  

output

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})
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
  • 1
    What if the input array features a duplicated element? e.g. `[8, 8, 2, 1, 3]` There are two subsets of sum 11, but this method will not capture them. – asongtoruin Feb 16 '17 at 11:00
  • @asongtoruin True, but I decided to assume that we're working with true sets, which don't contain duplicates. ;) If the original set contains two `8`s, does `({8}, {8})` count as a valid partition? – PM 2Ring Feb 16 '17 at 11:11
  • Excellent use of itertools. But so complex, after you have the subsets you can just iterate over them and check `if sum(sub) == sum(seq) / 2` That is it. – JanHak Feb 16 '17 at 11:27
  • 1
    @Janhak That would work if we were literally partitioning `seq` into 2 parts, but we aren't doing that. The example in the OP is `[8]` and `[3,5]`, which doesn't completely cover the original set. – PM 2Ring Feb 16 '17 at 13:19
0

I found a solution, but it will raise a memory error for larger inputs :(

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
yzcop
  • 21
  • 4