我一直在寻找一种算法来解决维度'n'的所有可能矩阵,这些矩阵可以通过两个数组获得,其中一个是行的总和,另一个是列的总和。矩阵。例如,如果我有以下维度7的矩阵:
matriz= [ 1 0 0 1 1 1 0
1 0 1 0 1 0 0
0 0 1 0 1 0 0
1 0 0 1 1 0 1
0 1 1 0 1 0 1
1 1 1 0 0 0 1
0 0 1 0 1 0 1 ]
列的总和是:
col = [4 2 5 2 6 1 4]
行的总和是:
row = [4 3 2 4 4 4 3]
现在,我想获得所有可能的“1和0”矩阵,其中列和行的总和分别满足“col”和“row”的条件。
我很感激可以帮助解决这个问题的想法。
答案 0 :(得分:1)
一种显而易见的方法是强制解决方案:对于第一行,生成具有正确总和的所有可能性,然后对于每一种,生成第二行的所有可能性,依此类推。生成所有行后,检查列的总和是否正确。但这需要很多时间。我的数学可能在一天中的这个时候生锈,但我相信binomial coefficient或nchoosek(n,k)
或n
给出k
位为1的>> n = 7;
>> row= [4 3 2 4 4 4 3];
>> prod(arrayfun(@(k) nchoosek(n, k), row))
ans =
3.8604e+10
行的不同可能性的数量。 Matlab中的{{3}}。要确定可能性的总数,您必须为每一行乘以此数字:
>> col= [4 2 5 2 6 1 4];
>> prod(arrayfun(@(k) nchoosek(n, k), col))
ans =
555891525
这有很多可能性来检查!为列做同样的事情
{{1}}
仍然是一个很大的数字,但“只”减少70倍。
通过查看后面的行是否已被前一行约束,可能会稍微改进这种强力方法。如果在您的示例中,对于前两行的特定组合,两行在第二列中都有1,则此列的其余部分都应为0,因为总和必须为2.这减少了可能的数量。剩余的行有点。实施此类检查可能会使事情变得复杂,但它们可能会使计算花费2天或者只花费1小时。
此优化版本可能会生成行和列,并从可能性最低的那些开始。我不知道是否有比这种蛮力方法更优雅的解决方案,我很想听到一个。