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

如何用Python按指定行列和规则拼接9个3×3矩阵为9×9矩阵?

解决方案:回溯法+剪枝优化

针对你的问题,暴力随机拼接效率极低,而回溯法结合约束剪枝是更高效的方案——通过提前排除不符合部分约束的排列,避免遍历所有9!种可能。

步骤1:预处理矩阵属性

首先,为每个小矩阵计算关键属性,方便后续快速验证约束:

  • 每个小矩阵的3行的和(用于计算大矩阵的行和)
  • 每个小矩阵的3列的和(用于计算大矩阵的列和)
  • 小矩阵的对角线和(用于大矩阵主对角线总和)
  • 小矩阵的反对角线和(用于大矩阵副对角线总和)

步骤2:回溯填充+剪枝

按行优先顺序填充3×3的小矩阵网格,每放置一个矩阵后,立即检查当前已填充部分是否违反约束:

  • 若某一行的3个小矩阵已填满,验证对应大矩阵的3行和是否符合目标
  • 若某一列的3个小矩阵已填满,验证对应大矩阵的3列和是否符合目标
  • 当主对角线的3个小矩阵(M00、M11、M22)都填满时,验证主对角线总和
  • 当副对角线的3个小矩阵(M02、M11、M20)都填满时,验证副对角线总和

不符合约束的分支直接回溯,无需继续深入,大幅减少计算量。

完整代码实现

import numpy as np

# 定义所有3×3矩阵
matrices = [
    np.array([[0, 0, 0], [0, 1, 0], [0, 0, 0]]),    # matrix1
    np.array([[0, 0, 1], [0, 0, 0], [1, 0, 0]]),    # matrix2
    np.array([[0, 0, 1], [0, 1, 0], [1, 0, 0]]),    # matrix3
    np.array([[1, 0, 1], [0, 0, 0], [1, 0, 1]]),    # matrix4
    np.array([[1, 0, 1], [0, 1, 0], [1, 0, 1]]),    # matrix5
    np.array([[1, 1, 1], [0, 0, 0], [1, 1, 1]]),    # matrix6
    np.array([[1, 1, 1], [1, 0, 0], [1, 1, 1]]),    # matrix7
    np.array([[1, 1, 1], [1, 0, 1], [1, 1, 1]]),    # matrix8
    np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])     # matrix9
]

# 预处理每个矩阵的属性:行和、列和、对角线和、反对角线和
mat_attrs = []
for mat in matrices:
    row_sums = [sum(row) for row in mat]
    col_sums = [sum(col) for col in mat.T]
    diag_sum = sum(mat.diagonal())
    anti_diag_sum = sum(mat[:, ::-1].diagonal())
    mat_attrs.append((row_sums, col_sums, diag_sum, anti_diag_sum))

# 目标约束
target_row_sums = [9, 4, 9, 5, 2, 5, 4, 3, 4]
target_col_sums = [5, 4, 5, 7, 4, 7, 5, 4, 4]
target_diag1 = 6
target_diag2 = 6

# 回溯函数
def backtrack(grid, used, pos):
    # pos是当前要填充的位置索引(0~8,对应3x3网格的行优先顺序)
    if pos == 9:
        # 所有矩阵已填充,验证最终约束(其实前面剪枝已经确保符合,这里做最终确认)
        return verify_full_constraints(grid)
    
    row = pos // 3
    col = pos % 3
    
    for idx in range(9):
        if not used[idx]:
            # 尝试放置当前矩阵到grid[row][col]
            grid[row][col] = idx
            used[idx] = True
            
            # 检查当前部分约束,剪枝
            if check_partial_constraints(grid, used, row, col):
                # 递归填充下一个位置
                result = backtrack(grid, used, pos + 1)
                if result is not None:
                    return result
            
            # 回溯
            grid[row][col] = -1
            used[idx] = False
    
    return None

def check_partial_constraints(grid, used, row, col):
    # 检查当前行的小矩阵是否填满,验证对应大矩阵的3行和
    if all(grid[row][c] != -1 for c in range(3)):
        # 计算大矩阵的row*3, row*3+1, row*3+2行的和
        for i in range(3):
            total = 0
            for c in range(3):
                mat_idx = grid[row][c]
                total += mat_attrs[mat_idx][0][i]
            if total != target_row_sums[row*3 + i]:
                return False
    
    # 检查当前列的小矩阵是否填满,验证对应大矩阵的3列和
    if all(grid[r][col] != -1 for r in range(3)):
        # 计算大矩阵的col*3, col*3+1, col*3+2列的和
        for i in range(3):
            total = 0
            for r in range(3):
                mat_idx = grid[r][col]
                total += mat_attrs[mat_idx][1][i]
            if total != target_col_sums[col*3 + i]:
                return False
    
    # 检查主对角线(M00, M11, M22)是否填满,验证主对角线总和
    if row == col and all(grid[r][r] != -1 for r in range(3)):
        total = 0
        for r in range(3):
            mat_idx = grid[r][r]
            total += mat_attrs[mat_idx][2]
        if total != target_diag1:
            return False
    
    # 检查副对角线(M02, M11, M20)是否填满,验证副对角线总和
    if row + col == 2 and all(grid[r][2 - r] != -1 for r in range(3)):
        total = 0
        for r in range(3):
            mat_idx = grid[r][2 - r]
            total += mat_attrs[mat_idx][3]
        if total != target_diag2:
            return False
    
    return True

def verify_full_constraints(grid):
    # 构建最终的9×9矩阵(可选,用于输出结果)
    big_mat = np.zeros((9,9), dtype=int)
    for r in range(3):
        for c in range(3):
            mat_idx = grid[r][c]
            big_mat[r*3:(r+1)*3, c*3:(c+1)*3] = matrices[mat_idx]
    
    # 验证所有约束(可选,确保结果正确)
    assert np.array_equal(big_mat.sum(axis=1), target_row_sums)
    assert np.array_equal(big_mat.sum(axis=0), target_col_sums)
    assert big_mat.diagonal().sum() == target_diag1
    assert big_mat[::-1].diagonal().sum() == target_diag2
    
    return grid, big_mat

# 初始化网格(-1表示未填充)和已使用标记
initial_grid = [[-1]*3 for _ in range(3)]
initial_used = [False]*9

# 执行回溯
result = backtrack(initial_grid, initial_used, 0)

if result:
    grid, big_mat = result
    print("找到符合条件的小矩阵排列(3×3网格,数字对应matrix1~matrix9的编号):")
    for row in grid:
        print([idx+1 for idx in row])
    print("\n拼接后的9×9矩阵:")
    print(big_mat)
else:
    print("未找到符合条件的排列(若你确认纸上存在,可检查矩阵编号对应是否有误)")

代码说明

  1. 预处理阶段:提前计算每个小矩阵的行和、列和等属性,避免重复计算,提升验证效率。
  2. 剪枝逻辑:每放置一个矩阵后,立即检查已填充的行/列/对角线是否符合约束,不符合则直接回溯,跳过无效分支。
  3. 结果验证:找到候选排列后,构建完整9×9矩阵并验证所有约束,确保结果正确。

运行代码后,会输出小矩阵的排列顺序以及最终拼接的9×9矩阵,完全匹配你给出的约束条件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 03:35:05