【发布时间】:2021-03-30 06:58:05
【问题描述】:
我有一个由 N 个元素组成的集合 S。每个元素由一串长度为 L 的位表示。
例如,当 L=5 时,S 可以由{ 01010, 01100, 10100, 00001 } 组成
如果一对元素没有任何共同位(即如果它们的按位与为零),则它们是兼容的。例如:
- 01010 与 01100 不兼容,因为
01010 & 01100 = 01000(非零) - 01010 与 10100 兼容,因为
01010 & 01010 = 00000(零)
如果 S 的所有元素的成对按位与为零,则 S 的子集是兼容的。
例如,子集{ 01010, 10100, 00001 } 是兼容的,因为以下所有陈述都是正确的
01010 & 10100 = 0
01010 & 00001 = 0
10100 & 00001 = 0
我想找到 S 的所有可能兼容的子集。 鉴于上述 S 的示例,这将是:
{ 01010 }
{ 01100 }
{ 10100 }
{ 00001 }
{ 01010, 10100 }
{ 01010, 00001 }
{ 01100, 00001 }
{ 10100, 00001 }
{ 01010, 10100, 00001 }
实现这一目标的最佳算法是什么?
这个问题可以用图来重新表述,其中 S 的每个元素都是一个节点,兼容的元素由边连接。在这种情况下,问题变成了找到所有可能的节点集完全连接(即每对节点之间是否存在直接边)。
【问题讨论】:
-
你想生成所有子集,还是简单地(没那么简单)对它们进行计数?
-
我要生成所有子集。
-
这与stackoverflow.com/questions/30893292/… 本质上是同一个问题(表述为位向量而不是集合,但算法相同)。
-
@rici,我不太明白你提到的问题。例如,它声明2个分区的交集是空集,然后作为例子,它使用{1,2,3}和{1,2},它们显然没有空交集。但是,我投票赞成你对那个问题的回答,这与我自己提出的算法非常相似。
-
@fabio:我认为问题中的示例很难阅读,因为它们是一起运行的;我添加了一些可能会有所帮助的新行。当我这样做时,我注意到我在评论中留下了指向有效解决方案的链接;值得注意的是,五年后链接仍然很好:ideone.com/6vaXaN
标签: algorithm set graph-algorithm combinatorics