algorithm – 在矩阵中查找k个不相交行的组

问题陈述:设S是一组整数,例如S = {1,2,…,12}. M是整数矩阵,其行可以被视为S的子集,其长度除以S的元素的数量,特别是M的每一行仅包含不同的元素/整数.我正在尝试生成Matlab代码,该代码可以识别M的不相交行的所有组,其集合理论联合给出S(即,具有固定大小的子集中的S的分区)并且将每个这样的组作为矩阵返回.

示例:A = [1 2 5 6; 3 4 11 12; 9 10 7 8]是S的分区,而B = [1 2 3 4; 5 6 7 8; 9 10 11 12; 1 5 9 12]不是S的分区(因为最后一行与前三行不相交).

数量级:通常,M将具有~500 000行,S将具有多达100个元素.

到目前为止的方法:设m = size(M,1),n = size(M,2)(分区子集的大小),s = | S | (要分区的集合的大小)和k = s / n(形成分区所需的不相交行的数量 – 您可以假设s = 0 mod n,因此问题是明确定义的).注意,为了建立这样的分区,足以检查行的不相交性并且确实存在多个行.

对于j = 1:(mk 1),我观察到ind =(sum(ismember(M((j 1):m,:),M(j,:)),2)== 0),这给了我M(j,:)之后的行的索引列也与它不相交.然后我通过将M(j,:)与这些行中的每一行组合来创建2 x n矩阵.之后,我想用所有这些新的2 x n矩阵重复ismember()例程并继续重复,直到我得到k x nmatrices.这可能都是好事和花花公子,但它也是我绊倒的地方,因为,对于一个,例程的数量取决于k.

问题:

(Q1)如何完成我的方法代码?

(Q2)是否有更好的方法解决这个问题(即更快,矢量化/更少循环,GPU辅助),如果是,它们是什么?

最佳答案 这个问题是
exact cover的一个非常特殊的情况.如果你在C中工作,我会建议
Knuth’s Algorithm X,用
bit arrays而不是
dancing links实现,因为你关注的实例的表观密度.我希望MATLAB几乎可以容纳你.

作为整数,集合{1,2,5,6}可以表示为2 ** 1 2 ** 2 2 ** 5 2 ** 6.然后两个集合的交集表示为它们的表示的bitwise and,并且两个集合的并集是按位或.空集为0.不幸的是,对于S = 100,您将需要使用两个或更多整数,这会使生命复杂化.拍摄一组之后,您可以通过矢量化位来检测与其他集合的交叉点.

点赞