找到所有可能的套装

时间:2011-10-11 14:32:53

标签: algorithm matlab

假设我有一个大小为S的矩阵(m,n),其中m是集合数,n所有可能元素集的数量都可以。在此矩阵中,如果条目S(i,j)1,则集i具有元素j,否则元素S(i,j)0

我的问题是:是否有任何已知的相对有效的算法来枚举所有可能的集合填充(即集合的组合使得没有两个集合相交)?

使用此表示法,将包装k定义为向量 p_k = [p_{k,1}, p_{k,1}, ... p_{k,km}]其中元素p_{k,r}S中的行索引(即集合),以使p_k中的集合的交集为0。换句话说,p_{k,r} * p_{k,s}'p_k索引的任意两行向量S的内积为0

我正在寻找MATLAB中的实现(或者可以从MATLAB中调用的东西),但如果有人知道其他库中的快速实现,那也会有所帮助。

2 个答案:

答案 0 :(得分:1)

我担心效率不高,但肯定不仅仅是蛮力。

我知道包装的基数范围从1到(最多)m。

要找到所有可能的解决方案,请从基数1开始并迭代直到:

  • 您到达m

  • 或者下一次迭代没有更多的候选人(详见下文)。

候选矩阵与S具有相同的形式。在迭代n,它包含在迭代n-1处找到的有效打包的元素。它在迭代1中初始化为S值。

在每个基数步骤

  • 对于候选矩阵的每一行,您检查是否可以通过添加矩阵S的一行(且仅一行)来构建仍然有效的多个包装:

    • 您遍历S的每一行(如果您跳过已经在包装中的行,则可以更快地进行此操作)。如果它有效,则将所考虑的行索引附加到打包,将此打包作为新结果发送,并将其添加到 future,next iteration 候选矩阵(在每个基数步骤中将更小,因为某些组合导致无效的包装)。

这样,候选矩阵在每次迭代时越来越小,一旦没有候选者就可以停止。

实施例

S=
 1 0 0 1  (a)
 1 1 0 0  (b)
 0 0 1 0  (c)

迭代1

(初始化):产生3个结果和候选:a,b和c(初始化)

<强>结果

(a,b,c)

<强>候选信息

 1 0 0 1  (a)
 1 1 0 0  (b)
 0 0 1 0  (c)

迭代2

迭代候选人,然后是行:

  • 选择候选人

    • 跳过行a(优化1)
    • 尝试将其与行b组合 - &gt;失败
    • 尝试将其与行c结合 - >成功
      • 下次新结果(ac)和新候选人(ac)
  • 选择候选人b

    • 尝试将其与行a - &gt;结合使用失败
    • 跳过第b行(优化1)
    • 尝试将其与行c结合 - >成功
      • 下次新结果(bc)和新候选人(bc)
  • 选择候选人c

    • 跳过a - &gt; (已经存在)
    • 跳过c - &gt; (已经存在)
    • 跳过行c(优化1)

新结果矩阵     (A,B,C,AC,BC)

新的候选人矩阵

 1 0 1 1 (ac)
 1 1 1 0 (bc)

迭代3

与上述相同......

  • 选择候选人(ac)

    • 跳过行a(优化1)
    • 尝试将其与行b组合 - &gt;失败
    • 跳过行c(优化1)
  • 选择候选人(bc)

    • 尝试将其与行a - &gt;结合使用失败
    • 跳过第b行(优化1)
    • 跳过行c(优化1)

没有更多候选人:结束。

最终结果矩阵     (A,B,C,AC,BC)

最终候选人矩阵

 ()

关于优化

  • 优化1是:无需尝试将行与已包含它的打包候选项组合

答案 1 :(得分:1)

不能有任何多项式顺序算法来枚举您的问题的所有可能的填充,因为存在指数级的这种填充。例如,对于m,n = 3,4,有2 ^(n-1)个打包配置,包括所有n个元素:{abcd},{a} {bcd},{ab} {cd},{abc} {d},{a} {b} {cd},{a} {bc} {d},{ab} {c} {d},{a} {b} {c} {d}。 (推测集合没有区分; 例如 {abc} {d}相当于{d} {abc}。如果集合 区分,则在以下方法中只计算而不排除任何计数,不适用规则。)

这个答案的其余部分可能会提供一些解决问题的想法或框架,但(按原样)可能效率不高。

枚举所有有效情况的一种方法是将基数m + 1数H从H = 0计算到一小部分(m + 1)^ n,应用一些规则来选择有效配置。设d.j表示H的第j位,d.1最不重要。如果d.j为0,则元素j是no set的成员;如果d.j = k> 0,j是集合k的成员。设A.i(H)= H中数字i的最高位置,如果-i未出现,则为i;要求A.i&gt; A.第(i + 1)。当H计数时,A(H)可以在O(1)时间内逐步维持和测试。例如,要在以下(手工)示例中排除1323(== 1232),请注意A.2(1323)= 2&lt; 3 = A.3(1323)。

示例:n = 4 = #elements; m = 3 = #sets;具有难以区分的组的H序列应为:0000,0001,0010,0011,012,0100,0101,0102,0110,0111,0112,0120,0121,0122,0123,1000,1001,11010,1011,1012,1100 ,1101,1102,1110,1111,1122,1120,1121,1122,1123,1200,1201,1202,1203,1210,1211,1212,1213,1220,1221,1222,1223,1230,1231,1232,1233