一组列表的规范形式

时间:2019-04-13 15:38:09

标签: algorithm math matrix data-structures combinatorics

我得到了两个无序集合,每个集合包含n项的m个列表。 m = 4和n = 3的示例:

D1 = {[4,2,1], [3,3,1], [4,2,3], [1,2,1]}
D2 = {[3,2,3], [4,2,3], [1,1,3], [4,2,1]}

如果两个元素在各自列表中的元素之间存在一一对应的关系,则认为这两个元素是等效的。在上面的示例中,D1和D2是等效的,因为D1中有一个赋值(1,2,3,4)↔(3,2,1,4)在D2中。

在此示例中,项目是数字,但这并不重要,因为我只关心两个集合之间的等价关系,而不关心项目本身。

我正在寻找一种快速的方法来检查两个给定的集合是否相等。可以以唯一(规范)形式对集合进行序列化,而不是执行回溯搜索来查找项目之间的分配,这样,如果两个集合的规范形式相同,就可以证明它们是等效的?

更新:尽管这个问题似乎通常很难解决(请参见下面的答案),但事实证明,使用回溯搜索对于我的数据实际上是行之有效的。下面是我的实现的伪代码:

s = new stack(of level)
x1_x2 = new dictionary(of int, int)
bound_x2s = new set(of int)

function setsEquivalent(d1: set, d2: set) : boolean
    if d1.m <> d2.m or d1.n <> d2.n: return false        
    s.push(new level)
    do until s.size = 0
        m1 = s.size
        m2 = s.top.m2
        if m1 > m
            return true
        elseif s.top.m2 > m
            backtrack()
        else                
            s.push(new level)
            for k = 1..n
                if not try_bind(d1.m(m1)(k), d2.m(m2)(k))
                    backtrack()
                    exit for
    return false

function try_bind(x1: int, x2: int) : boolean
    if x1_x2.containskey(x1)
        return x1_x2(x1) = x2
    elseif bound_x2s.contains(x2)
        return false
    else
        x1_x2.add(x1,x2)
        bound_x2s.add(x2)
        s.top.boundx1s.add(x1)
        return true

procedure backtrack()
    for each x1 in s.top.boundx1s:
        bound_x2s.remove(x1_x2(x1))
        x1_x2.remove(x1)
    s.pop
    if s.size <> 0
      s.top.m2 += 1

record level
    m2 = 1
    boundx1s = new list(of int)

1 个答案:

答案 0 :(得分:1)

您的问题至少与Graph Isomorphism Problem一样困难。有向图可以表示为一组长度为2的列表,这是问题的特例。此外,已知有向图同构问题与图同构问题具有相同的复杂性。因此,问题的特殊情况与全图同构问题一样困难。图同构的确切复杂性尚不清楚。尽管没有推测它是NP完整的,但尚无已知的多项式时间算法。

由于图同构问题没有简单的解决方案,因此我怀疑序列化是否可以为您的问题提供简单的解决方案。