【问题标题】:Comparing collections of subsets up to permutation比较子集的集合直至排列
【发布时间】:2010-11-07 21:07:39
【问题描述】:

我有一个数组 a[i][j]。元素是 char,解释为集合 {1,...,8} 的子集(如果第 k 位为 1,则元素 k 在子集中)。我认为这无关紧要,但每个元素都设置了 4 位。

每一行 a[1][j]..a[n][j] 是 {1,...,8} 的子集的集合。我需要删除重复的行,如果可以通过 {1,...,8} 的排列从另一行获得两行,则将两行视为重复行。

示例(0bxxxxxxxx 表示二进制数):

0b11000000, 0b01100000, 0b00110000

重复
0b00110000, 0b00011000, 0b00100100

因为前者可以通过应用排列从后者得到

8->8, 7->7, 6->1, 5->4, 4->3, 3->2, 2->5, 1->6

并重新排序结果。

出于性能考虑,该数组包含大约 2000 行,每行最多包含 20 个元素。如果这可能有帮助,每一行都已经排序,并且这些行也是按字典顺序递增的。算法的其余部分是用 C 编写的,因此首选 C 解决方案。

感谢您的帮助。

【问题讨论】:

    标签: c algorithm duplicate-removal


    【解决方案1】:

    如果所有子集都有 2 个元素,则表示 graph isomorphism,子集表示图边。 这甚至更普遍(因此可能更难),所以我会看看用于解决图同构的启发式方法,看看它们是否适用于这里。

    有很多图同构启发式可以廉价地排除同构。对于特定的集合,您可以计算每个元素属于多少个子集,然后对其进行排序。在您的示例中,两个集合都会得到 [2,2,1,1,0,0,0,0]。如果两个集合的排序序列不同,则不存在同构。当然,平等并不能保证存在。

    还有更多类似的启发式方法更擅长筛选非同构图(并且可能适用于此)。

    还有,8!只有 40320,所以暴力破解所有排列并非完全不可行。

    【讨论】:

    • 在图论中,这是 4-uniform 超图的同构问题。我设法做了一些特别的简化,使问题适合暴力破解,但我仍然想知道好的通用算法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    相关资源
    最近更新 更多