假设我有一个大小为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中调用的东西),但如果有人知道其他库中的快速实现,那也会有所帮助。
答案 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)
(初始化):产生3个结果和候选:a,b和c(初始化)
<强>结果
(a,b,c)
<强>候选信息
1 0 0 1 (a)
1 1 0 0 (b)
0 0 1 0 (c)
迭代候选人,然后是行:
选择候选人
选择候选人b
选择候选人c
新结果矩阵 (A,B,C,AC,BC)
新的候选人矩阵
1 0 1 1 (ac)
1 1 1 0 (bc)
与上述相同......
选择候选人(ac)
选择候选人(bc)
没有更多候选人:结束。
最终结果矩阵 (A,B,C,AC,BC)
最终候选人矩阵
()
答案 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