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



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

给定是一个具有 n (n<=30) 个节点和 m (m<=50) 条边的无向图,每条边都以 a, b 格式表示,其中a, b都是图中的节点。

现在在这个图中,我们必须计算节点的所有子集,显然有 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的循环

我试过什么

我用正确答案解决了这个问题,但它仅在n<=22 时才有效,实际上我正在生成所有可能的 O(2^n) 复杂度的位掩码,但这个复杂度对于n=30来说太大了。我应该向我的算法添加什么才能使其适用于所有测试用例?

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

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

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

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

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

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

如果两个三角形共享两个节点,我们计算 0111 而不是 1111,因此得到 2n-2 n-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 ×2 47
包含 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 ×2 47
包含 I 但不包含 A 到 H 的子集数为 7/8 × 7/8 × 25/32 × 3/16 × 1/2 × 1/2 ×2 47

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

最新更新