比较子集的集合直到排列

时间:2009-07-03 08:28:29

标签: c algorithm duplicate-removal

我有一个数组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解决方案。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

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

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

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

另外,8!只有40320,所以强制所有的排列并不是完全不可行的。