等和子集混合

发布于 2024-07-13 12:14:35 字数 467 浏览 11 评论 0原文

问题如下:

给定一组正整数 { a1 , a2 , a3 , ... , an },其中没有相同的数字( a1 只存在一次,a2 只存在一次,...)例如A = {12 , 5 ,7 ,91 }。 问题: A 是否有两个不相交的子集 A1 = { b1,b2,...,bm } 和 A2 = { c1,c2,...,ck} 使得 b1+b2+...+bm = c1+ c2+...+ck ?

请注意以下事项: A1 和 A2 不一定要覆盖 A,因此问题不会自动简化为子集和问题。 例如 A = {2,5,3,4,8,12} A1= {2,5} 所以 A1 之和为 7 A2= {3,4} 所以 A2 之和为 7 我们发现 A 的两个不相交子集具有所描述的属性,因此问题得到解决。

我怎么解决这个问题? 我能做一些比找到所有可能的(不相交)子集、计算它们的总和并找到两个相等的总和更好的事情吗?

感谢您的时间。

The problem is the following:

You are given a set of positive integers { a1 , a2 , a3 , ... , an } in which there are no same numbers ( a1 exists only once ,a2 exists only once,...) eg A = {12 , 5 ,7 ,91 }.
Question: Are there two disjoint subsets of A , A1 = { b1,b2,...,bm } and A2 = { c1,c2,...,ck} so that b1+b2+...+bm = c1+c2+...+ck ?

Note the following: It is not obligatory for A1 and A2 to cover A, so the problem isn't automatically reduced to the subset sum problem.
eg A = {2,5,3,4,8,12}
A1= {2,5} so sum of A1 is 7
A2= {3,4} so sum of A2 is 7
We found two disjoint subsets of A with the described property so the problem is solved.

How can I solve this problem? Can I do something better than find all possible (disjoint)subsets, calculate their sums and find two equal sums?

Thank you for your time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

べ映画 2024-07-20 12:14:37

这个问题看起来至少和 SUBSET-SUM 一样难。 如果我们可以找到 A 的两个子集:B = {b1,...,bp} 和 C = {c1,...,cq} 使得 b1+...+bp = -c1-...-cq,或者如果我们确定不存在,那么我们就解决了 SUBSET-SUM(A)(忽略 0 ∈ A 的简单情况)。

我不确定你的意思是 B 和 C 没有义务覆盖 A,所以问题不会自动简化为子集和问题。 请检查SUBSET-SUM的定义。

This problem seems to be at least as hard as SUBSET-SUM. If we can find two subsets of A: B = {b1,...,bp} and C = {c1,...,cq} such that b1+...+bp = -c1-...-cq, or if we determine that none exist, then we have solved SUBSET-SUM(A) (ignoring the trivial case where 0 ∈ A).

I'm not sure what you mean by it is not obligatory for B and C to cover A, so the problem isn't automatically reduced to the subset sum problem. Please check the definition of SUBSET-SUM.

活泼老夫 2024-07-20 12:14:36

没问题,这是一个 O(1) 解决方案。

A1 = {}; 
A2 = {};
sum(A1) == sum(A2) /* == 0 */

量子电子器件。


说真的,您可以进行的一项优化(假设我们正在讨论正数)是仅检查小于或等于 sum(A)/2 的子集。

对于 A 中的每个元素,都有三个选项使其成为 O(3^N)

  1. 将其放入 A1
  2. 将其放入 A2
  3. 丢弃它

这是 Perl 中的一个简单的解决方案(计算匹配数,如果您只想测试是否存在,可以提前返回)。

use List::Util qw/sum/;

my $max = sum(@ARGV)/2;
my $first = shift(@ARGV); # make sure we don't find the empty set (all joking aside) and that we don't cover same solution twice (since elements are unique)
my $found = find($first,0, @ARGV);
print "Number of matches: $found\n";

sub find {
    my ($a, $b, @tail) = @_;
    my $ret = $a == $b? 1 : 0; # are a and b equal sub-sets?
    return $ret unless @tail;

    my $x = shift @tail;
    $ret += find($a + $x, $b, @tail) if $a + $x <= $max; # put x in a
    $ret += find($a, $b + $x, @tail) if $b + $x <= $max; # put x in b
    return $ret + find($a, $b, @tail); # discard x
}

No problem, here's an O(1) solution.

A1 = {}; 
A2 = {};
sum(A1) == sum(A2) /* == 0 */

QED.


Seriously, one optimization you can make (assuming that we're talking about positive numbers) is to only check sub-sets less or equal to sum(A)/2.

For every element in A there are three options which makes it O(3^N):

  1. Put it in A1
  2. Put it in A2
  3. Discard it

Here's a naive solution in Perl (that counts the matches, you can have an early return if you just want to test existence).

use List::Util qw/sum/;

my $max = sum(@ARGV)/2;
my $first = shift(@ARGV); # make sure we don't find the empty set (all joking aside) and that we don't cover same solution twice (since elements are unique)
my $found = find($first,0, @ARGV);
print "Number of matches: $found\n";

sub find {
    my ($a, $b, @tail) = @_;
    my $ret = $a == $b? 1 : 0; # are a and b equal sub-sets?
    return $ret unless @tail;

    my $x = shift @tail;
    $ret += find($a + $x, $b, @tail) if $a + $x <= $max; # put x in a
    $ret += find($a, $b + $x, @tail) if $b + $x <= $max; # put x in b
    return $ret + find($a, $b, @tail); # discard x
}
画▽骨i 2024-07-20 12:14:36

如果答案是否定的,则所有 n 个数字的总和至少为 2^n-1。 因此,如果 n 很大,并且数字是 32 位整数,那么答案几乎总是肯定的。 如果 n 很小,你可能可以暴力破解。

最困难的情况可能是 n 约为 30 时。

If the answer is no, then the sum of all n numbers is at least 2^n-1. So if n is large, and the numbers are 32-bit integers, for instance, then the answer is almost always yes. If n is small, you can probably brute-force.

The hardest case is probably when n is around 30.

素衣风尘叹 2024-07-20 12:14:36

我认为你可以像子集和问题一样解决它。 取布尔函数 Q(i,s),如果 a0,a1,...,ai 的子集总和为 s 并且包含 ai,则该函数为 true。 您可以使用动态规划计算所有 i 和 s(这是标准方法)。 然后,您可以扫描 Q 的所有值,以查找在其关联行中具有多个真值的 s。

如果存在这样的 s,则意味着您找到了两个具有相同总和的不同子集。 它们可能不是不相交的,但是您可以从每个集合中删除公共元素,并得到两个总和相等的不相交集合。 不过,其中之一可能是空的。

I think that you can solve it just like the subset sum problem. Take the boolean function Q(i,s) which is true if a0,a1,...,ai have a subset that sums to s and contains ai. You can compute it for all i and s using dynamic programming (this is the standard approach). Then, you can scan all values of Q for s that has more than one true value in its associated row.

If such s exists, it means that you found two different subsets that have the same sum. They might not be disjoint, but then you can remove the common elements from each set and get two disjoint sets with equal sums. One of them might be empty, though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文