【问题标题】:Counting all sub-sets that are not forming forbidden combinations计算所有未形成禁止组合的子集
【发布时间】:2017-10-22 13:23:51
【问题描述】:

我正在尝试用组合数学和图形解决相当复杂的问题:

Given 是一个有 n (nm (ma,b的格式表示,其中a,b都是图中的节点。 p>

现在在这个图中,我们必须计算节点的所有子集,显然有 2^n 个子集,但是我们在每个子集组合中都有一个限制,我们不应该有三个节点正在形成三角形,我们不应该计算这些组合,换句话说,我们不应该计算包含长度为 3 的节点的组合。

示例

n=3, m=3 我们有图 2-1, 3-1, 2-3 ,这个例子的答案是 7,我们可以形成的所有子集是:{}、{1}、{2}、{3}、{1,2}、{1,3}、 {2,3},但是我们不应该计算子集 {1,2,3},因为节点 1,2,3 正在形成三角形,换句话说,它们正在形成长度为 3 的循环

我的尝试

我用正确的答案解决了这个问题,但它只在 nn) 生成所有可能的位掩码复杂性,但这种复杂性对于 n=30 来说太大了。我应该在我的算法中添加什么以使其适用于所有测试用例?

【问题讨论】:

  • 你知道有多少子集。如果你找到一个三角形,有多少个子集包含这个三角形?如果你找到两个三角形,有多少个子集包含这两个三角形?
  • 查找所有三角形,而不是为每个节点存储它所在的三角形(足以存储具有最大索引的节点的其他三角形节点),并且通过检查任何三角形中的节点和回溯查找组合是否已经选择了其他两个三角形节点。
  • @Ante 你能解释一下回溯部分吗,因为我不太了解你,因为有 30 个节点,我认为回溯的复杂度为 2^30
  • @someone12321 我误解了问题,我认为问题是打印所有子集,而不仅仅是子集的数量。我删除了我的答案。如 m69 所述,您需要 inclusion–exclusion principle A_i 是包含三角形 i 的子集。问题是求和存在于三角形的每个子集上,它可能比所有节点子集的数量大得多。每个和的类型为 |intersection A_x| = 2^(n-number_of_different_nodes_in_trias),可以用来简化求和。
  • @someone12321 它有效 :-) 最简单的方法是只检查一个三角形。比解决方案是|S| - |A_1| = 2^n - 2^(n-3)。这包括具有一个或两个三角形节点的子集。

标签: algorithm graph combinatorics


【解决方案1】:

有效解决这个问题的关键当然是只计算有或没有三角形的子集有多少,而不是实际生成任何子集来检查它们。

正如您所说,具有 n 个节点的图具有 2n 个可能的子集,并且每个可能的 n 大小的位模式代表其中一个子集。请注意,我们不需要生成这些子集来计算有多少。

现在,想象一下,在检查了边之后,我们找到了一个三角形。 2n 个子集中有多少个包含构成这个三角形的所有三个节点?三个相应位始终设置为 111 的所有 n 大小的位模式表示包含这三个节点的所有子集。这些位模式的数量显然是 2n-3。因此,如果我们有 n 个节点和 1 个三角形,我们就有 2n-2n-3 个不包含三角形的子集。

如果有 2 个或更多三角形,问题是:我们应该从总数中减去多少额外的子集?假设有 2 个三角形,它们不共享任何节点。那么一个三角形排除了 2n-3 个子集,包含第二个三角形但不包含第一个三角形的子集数(我们不想两次排除任何子集)为 7/8 × 2 n-3,因为它们对应于所有 n 大小的位模式,其中 3 位始终设置为 111,其他 3 位设置为 000、001、010、011、100、101、110,但不是 111。所以如果我们有 n 个节点和 2 个独立的三角形,我们有 2n-2n-3-7/8×2n-3 不包含三角形的子集。

如果有第三个三角形不与前两个三角形共享任何节点,我们排除额外的 49/64×2n-3 个子集,因为有两组 3不能是 111 的位,因此是 7/8 × 7/8 × 2n-3

那么如果两个三角形共享一个节点会发生什么?第二个三角形对应的3位必须是111,而第一个三角形对应的3位不能是111,所以数00111、01111、10111而不是11111。这样得到2n- 2n-3-3/4×2n-3

如果两个三角形共享两个节点,我们计算 0111 而不是 1111,因此得到 2n-2n-3-1/2×2 n-3

如您所见,通过找出有多少个三角形以及它们共享多少个节点,您可以计算出没有三角形的子集有多少,而无需实际生成子集并检查它们是否有三角形。


示例

我们有 50 个节点和 30 条边。检查边缘后,我们找到了这些三角形:

A.        B.        C.  D.        E.        G.  H.

  N         N         N   N         N         N - N
 / \       / \       / \ / \       / \       / \ /
N - N     N - N     N - N - N     N - N     N - N
                                   \ /       \ /
                                    N         N

                                  F.        I.

子集总数为 250
包含三角形 A 的子集数为 247
包含 B 但不包含 A 的子集数为 7/8 × 247
包含 C 但不包含 A 或 B 的子集的数量为 7/8 × 7/8 × 247
包含 D 但不包含 A 到 C 的子集数为 7/8 × 7/8 × 3/4 × 247
包含 E 但不包含 A 到 D 的子集数为 7/8 × 7/8 × 25/32 × 247
包含 F 但不包含 A 到 E 的子集数为 7/8 × 7/8 × 25/32 × 1/2 × 247
包含 G 但不包含 A 到 F 的子集数为 7/8 × 7/8 × 25/32 × 3/16 × 247
包含 H 但不包含 A 到 G 的子集数为 7/8 × 7/8 × 25/32 × 3/16 × 1/2 × 247
包含 I 但不包含 A 到 H 的子集数为 7/8 × 7/8 × 25/32 × 3/16 × 1/2 × 1/2 × 247

250 - (1 + 7/8 + 49/64 + 147/256 + 1225/2048 + 1225/4096 + 3675/32768 + 3675/65536 + 3675/131072) × 2 47 = 1,125,899,906,842,624 - 606,343,081,754,624 = 519,556,825,088,000

【讨论】:

  • 感谢您的回答,但我认为代码中的实现将非常困难,因为我们必须使用分数,如何以最简单的方式实现?
  • @someone12321 7/8×2^47 当然是 7×2^44,所以这不是问题。但的确,将这个答案转化为代码并非易事。
  • 你能解释一下你是怎么得到部分的(25/32)E而不是A到D是7/8×7/8×25/32×247。你为什么得到( 25/32)?
  • @someone12321 是的,这是困难的部分。对于每一组三角形,您必须计算有多少可能性导致一个或多个三角形。 C 和 D 共用一个节点,即 5 位,中间位由两个三角形共用; 11100、11101、11110 和 11111 具有 C,而 00111、01111、10111 和(再次)11111 具有 D;所以这是 32 个组合,其中 7 个已经被排除,所以 (32-7)/32 = 25/32。我不知道为所有类型的集群计算这个最简单的方法是什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-22
相关资源
最近更新 更多