基于Python生成满足约束的N阶0-1矩阵的里程表式组合
生成满足约束的N×N 0-1矩阵的所有组合
嘿,你的思路其实精准踩中了问题的核心!先把两个约束掰扯清楚,避免理解偏差:
- 每列恰好有一个1,剩下的元素全是0;
- 主对角线严格下方(也就是行号i > 列号j的位置)的元素必须全为0——换句话说,所有1只能出现在主对角线或者它的上方区域(i ≤ j)。
你的思路为什么可行?
你说的“初始第一行全为1,逐次把最后一列的1下移到底部,再处理倒数第二列”,本质上是一种回溯式的迭代生成法,完美适配这个问题的结构:
每个列j的1只能放在第1到第j行(因为行号超过j的话就属于对角线下方,违反约束2)。从最后一列开始处理,相当于先穷尽当前列的所有可能位置,再回溯到前一列去切换新的位置,接着再重新穷尽后面列的所有可能——这样既不会重复生成矩阵,也不会漏掉任何一种合法组合。
拿N=3举个实际例子
我们用3×3的矩阵来走一遍完整的生成流程,你就能更直观地理解:
- 初始状态:所有列的1都放在第1行,这是第一个合法矩阵:
[1, 1, 1] [0, 0, 0] [0, 0, 0] - 下移第3列的1到第2行,得到第二个矩阵:
[1, 1, 0] [0, 0, 1] [0, 0, 0] - 继续下移第3列的1到第3行,得到第三个矩阵:
[1, 1, 0] [0, 0, 0] [0, 0, 1] - 回溯到第2列:把第2列的1下移到第2行,同时把第3列的1重置回第1行,得到第四个矩阵:
[1, 0, 1] [0, 1, 0] [0, 0, 0] - 再次下移第3列的1到第2行,第五个矩阵:
[1, 0, 0] [0, 1, 1] [0, 0, 0] - 继续下移第3列的1到第3行,第六个(也是最后一个)矩阵:
[1, 0, 0] [0, 1, 0] [0, 0, 1]
这里总共有1×2×3=6个合法矩阵,正好对应每个列的可选位置数的乘积(列1只有1种选择,列2有2种,列3有3种)。
如果要写代码实现的话
可以用一个数组pos来记录每个列的1所在的行号,比如pos[j]代表第j列的1在第pos[j]行,初始时所有pos[j] = 1。然后按以下步骤循环:
- 根据当前的
pos数组生成对应的矩阵; - 从右往左找第一个列j,满足
pos[j] < j(也就是这个列的1还能下移); - 把
pos[j]加1; - 把j右边所有列的
pos[k]重置为1; - 重复步骤1-4,直到找不到符合条件的列j为止。
这个逻辑能高效生成所有合法组合,而且完全符合你一开始的思路方向。
内容的提问来源于stack exchange,提问作者Matthew Debat
相关产品推荐
相关产品推荐

