Algorithm 计算未形成禁止组合的所有子集

Algorithm 计算未形成禁止组合的所有子集,algorithm,graph,combinatorics,Algorithm,Graph,Combinatorics,我试图用组合数学和图形来解决相当复杂的问题: 给定的是一个有n(n的无向图,有效解决这个问题的关键当然是只计算有或没有三角形的子集的数量,而不是实际生成任何子集来检查它们 正如你所说,一个有n个节点的图有2n个可能的子集,每个可能的n大小的位模式代表这些子集中的一个。注意,我们不需要生成这些子集来计算有多少子集 现在,假设在检查了边之后,我们发现了一个三角形。2n个子集中有多少个包含构成这个三角形的所有三个节点?所有n个大小的位模式,三个对应的位总是设置为111,表示所有包含这三个节点的子集。这

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


给定的是一个有n(n的无向图,有效解决这个问题的关键当然是只计算有或没有三角形的子集的数量,而不是实际生成任何子集来检查它们

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

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

如果有两个或更多的三角形,问题是:我们应该从总数中减去多少额外的子集?假设有两个三角形,它们不共享任何节点。那么一个三角形不包括2n-3个子集,以及包含第二个三角形但不包含第一个三角形的子集的数量(我们不想两次排除任何子集)是7/8×2n-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×2n-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)×247=1125899906842624-606343081754624=519556825088000

您知道有多少子集。如果您找到一个三角形,有多少子集包含该三角形?如果您找到两个三角形,有多少子集包含两个三角形?查找所有三角形,而不是它所在的每个节点存储三角形(足以为索引最大的节点存储其他三角形节点),而不是通过回溯查找组合,方法是检查任何三角形中是否有节点,以及是否已选择了其他两个三角形节点。@Ante您能否稍微解释一下回溯部分,因为我不太理解您的意思,因为有30个节点,我想回溯将在2^30中complexity@someone12321我误解了问题,我想问题是打印所有子集,而不仅仅是子集的数量。我删除了我的答案。正如m69所述,你需要一个I是包含三角形I的子集。问题是求和是在三角形的每个子集上,它可以比所有节点子集的数量大得多。每个求和类型都是|交集A|x |=2^(n-numberofu不同的节点),可以用来简化求和。@someone12321它的工作原理是:-)最简单的方法是只检查一个三角形。解决方法是| S |-| A|u 1 |=2^n-2^(n-3)。这包括带有一个或两个三角形节点的子集。谢谢你的回答,但我认为代码中的实现将非常困难,因为我们必须使用分数,如何以最简单的方式实现这一点?@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。我不知道最简单的方法是什么来计算所有类型的簇。