You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效生成含n个1且行列无重复1的p×q矩阵及计数公式

问题:生成满足约束的p×q矩阵及计数公式

需求:生成所有p×q矩阵,要求矩阵恰好包含n个"1",且每行、每列最多存在一个"1"(类似国际象棋n车问题)。以下是p=4、q=4、n=2时的低效Python实现:

for i1 in range(4*4):
    x1, y1 = i1//4, i1%4
    for i2 in range(i1+1,4*4):  # 注:原代码中i应为i1,此处修正笔误
        x2, y2 = i2//4, i2%4
        if x1 != x2 and y1 != y2:
           print(x1,y1,x2,y2)

该方法存在效率低、n增大时逻辑繁琐的问题,疑问如下:

  • 是否存在向量化的实现方式?
  • 这类矩阵的计数公式是什么?

一、高效实现方案(含向量化优化)

可以利用组合排列的特性直接生成所有合法的"1"位置,避免无效遍历和判断。以下是基于itertools和numpy的优化实现:

import itertools
import numpy as np

p, q, n = 4, 4, 2

# 生成所有合法的"1"坐标组合
# 1. 从p行中选n个不重复的行
row_combinations = itertools.combinations(range(p), n)
# 2. 对每个行组合,生成n个不重复列的全排列(保证列唯一)
valid_positions = []
for rows in row_combinations:
    for cols in itertools.permutations(range(q), n):
        valid_positions.append(list(zip(rows, cols)))

# 向量化生成矩阵
matrices = []
for pos in valid_positions:
    mat = np.zeros((p, q), dtype=int)
    # 用numpy向量化赋值替代循环
    coords = np.array(pos).T
    mat[coords[0], coords[1]] = 1
    matrices.append(mat)

# 验证输出(打印前3个矩阵)
for idx, mat in enumerate(matrices[:3], 1):
    print(f"矩阵{idx}:")
    print(mat)

优势说明

  • 无需嵌套多层循环,n值变化时仅需调整参数,逻辑简洁
  • 直接通过组合排列筛选合法位置,避免原方案中大量无效遍历和条件判断
  • 利用numpy向量化赋值进一步提升矩阵生成效率

二、计数公式

这类矩阵的总数可通过组合数学推导得出:

  1. 从p行中挑选n个不同行的组合数为 $\binom{p}{n} = \frac{p!}{n!(p-n)!}$
  2. 给选中的n个行分配n个不同的列,等价于从q列中选n个列的排列数 $P(q, n) = \frac{q!}{(q-n)!}$

两者相乘即为总数量:
$$
\text{总数} = \binom{p}{n} \times P(q, n) = \frac{p! \times q!}{n!(p-n)!(q-n)!}
$$

也可等价表示为从q列选n个组合,再给n个行做排列:
$$
\text{总数} = P(p, n) \times \binom{q}{n} = \frac{p! \times q!}{(p-n)!n!(q-n)!}
$$

示例验证

当p=4、q=4、n=2时:
$\binom{4}{2} = 6$,$P(4,2)=12$,总数为 $6 \times 12 = 72$,与原方案遍历去重后的结果一致。


内容的提问来源于stack exchange,提问作者Nicolas Rougier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 18:32:06