【问题标题】:Sum of the product over all combinations with one element from each group所有组合与每组一个元素的乘积之和
【发布时间】:2010-01-20 07:39:52
【问题描述】:

鉴于我有 m 个非空的不同集合(标记为 Z[1]、Z[2]、...、Z[m]),我的目标是计算恰好有一个的所有可能子集的总和每个集合中的元素。每个子集的大小被定义为其成员的乘积。例如:

Z[ 1 ] = {1,2,3}

Z[ 2 ] = {4,5}

Z[ 3 ] = {7,8}

应该导致:

1*4*7 + 1*4*8 + 1*5*7 + 1*5*8 + 2*4*7 + 2*4*8 + 2*5*7 + 2*5*8 + 3*4*7 + 3*4*8 + 3*5*7 + 3*5*8 = 810

虽然这很容易编码(用任何语言),但这是对著名的subset sum problem 的重述吗?如果没有,请提供计算此总和的多项式时间算法(首选伪代码或 python!)。如果不存在多项式时间算法,请解释原因。

【问题讨论】:

  • 这是作业,对吧?
  • 以 m 表示的多项式?还是所有 Z 中的元素总数?
  • @Ipthnc - 这不是一个家庭作业问题,而是我遇到的一个真正的基于物理的问题。假设您有许多封闭的不同系统(Z1、Z2、...)都耦合到同一个水库(在固定 T 处)。现在只观察每个系统一次,通过这些观察,水库最可能的 T 是多少?我将其重述为一个计算问题,希望 CS 专业的学生比我有更深入的了解。
  • @recursive - 以 m 表示的多项式,我们假设 Z_i 的平均大小是有界的。
  • 天哪,可观察的水库......我的头已经很痛了。

标签: algorithm subset


【解决方案1】:

很容易看出 (1 + 2 + 3) * (4 + 5) * (7 + 8) = 810。

>>> from operator import mul
>>> from functools import reduce
>>> z = [{1,2,3}, {4,5}, {7,8}]
>>> s = reduce(mul, (sum(zz) for zz in z))
>>> s
810

What's the Python function like sum() but for multiplication? product()?

我个人认为 Guido 在 mul 方面做出了一个糟糕的决定。

【讨论】:

  • 在这里我认为问题很困难 - 事后看来,一切都容易得多(而且显而易见)!谢谢Ipthnc!
  • 好答案! (我 +1 了。)仅供参考:请注意,这种操作——“我有 N 个集合,我想进行组合,其中我从 N 个集合中的每个集合中都有一个成员”——被称为“采取集合的笛卡尔积”。 (然后您将成员相乘 - 并找到“产品” - 是巧合。)
  • @Dan H,那么对于其他同样快的“组合”是否有更通用的方法来解决这个问题?只是用不同的运算符代替 mul 和 sum 的问题吗?老实说,我不得不多次阅读您的评论,因为笛卡尔积在 sql 中也意味着某些东西......显然相关,但可能不一样。
【解决方案2】:
>>> z1 = [1, 2, 3]
>>> z2 = [4, 5]
>>> z3 = [7, 8]
>>> s = 0
>>> for a in z1:
        for b in z2:
            for c in z3:
                s += a*b*c      
>>> s
810

【讨论】:

  • 天真地它可以工作,但这会随着 |Z_i| 中的术语数量呈指数增长和 m 并没有回答问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-01
  • 1970-01-01
  • 2016-01-08
  • 1970-01-01
  • 1970-01-01
  • 2016-04-12
相关资源
最近更新 更多