我有一个布尔矩阵,例如
1 0 1 1 0 1
其中行名为 m1 , m2 , m3 (作为方法)和列 t1 和 t2 (作为测试)。
解释是一组行(方法),它们在任何列中都至少有一个“1”(每个测试至少要有一个方法匹配)。
在我们的例子中,解释的集合是:
{
{m2},
{m1,m2},{m1,m3},{m2,m3},
{m1,m2,m3}
}
我现在想要计算所有解释。
现在,我已经有两个可以解决问题的实现,一个是自上而下搜索解释,另一个是自下而上,但两者都在计算时间呈指数级增长(通过将行数增加一倍而增加一倍)。
这是一个已知的(可能是有效解决的)数学问题吗?
让事情变得简单的是,最后,我只需要解释每个方法的出现次数。在我们的示例中,这将是 m1 三次出现, m2 四次出现, m3 出现三次。
我现在的算法工作正常,直到让我们说26行。但进一步说,它变得非常缓慢。
感谢您的帮助!
答案 0 :(得分:1)
如果您能够满足近似概率并希望可扩展,Gibbs采样可能会起作用。基本思路非常简单:从全行解释开始,然后重复以下几行解释。
在限制中,包含给定行的样本的分数收敛到其真实值。在关键词“使用吉布斯采样的贝叶斯推断”下有一些实际的实现(你有一个统一的先验并观察到对于每一列,与它相关的行的分离是真的)。但是,由于我不是这方面的专家,所以我不能告诉你自己卷起的危险。
答案 1 :(得分:1)
我认为这可能是一个指数问题。例如,如果其中一个方法在每个列中都有一个,那么包含该方法的任何方法子集都是一个解释,因此如果有M个方法,则至少有2 ^(M-1)个解释;类似地,如果某些方法在任何列中都有一个,那么至少有2 ^(M-2)个解释。
这是一种方法,虽然仍然是指数,但我认为比枚举所有解释更快,特别是当有多个方法时。
设T(A,B)是A(一组方法)的子集数,在B(一组列)的每列中至少有一个1。
如果B为空,则T(A,B)是A的子集数,即2 ^ #A,其中A具有#A元素。 否则,如果A为空,则T(A,B)为0。 否则,如果i是A的元素(例如第一个),
T(A,B)= T(A \ {i},B \ m [i])+ T(A \ {i},B)
(这里A \ {i}是A而没有i,B \ m [i]是B而没有方法i中的任何列)
T可以非常简洁地编码为递归函数。
最后c [j],方法j在解释中出现的次数是
c [j] = T(A \ {j},C \ m [j])
其中C是所有列的集合。
答案 2 :(得分:0)
我不知道是否有一些指数可能的解释(这意味着你不能比指数更快地枚举它们)。
但是,您可以采用动态编程方式处理此问题,以消除重复工作:
or
他们的测试一起给出所有1
s):