如何用Python创建幻方?已实现矩阵但无法满足行列对角线和相等
Python 构造幻方的实用方法
幻方的核心要求是行、列及两条对角线的元素和完全相等,不同阶数的幻方有不同的高效构造方法,以下是针对常见阶数的实现方案:
1. 奇数阶幻方(n为奇数,如3、5、7...)
最经典的构造方式是暹罗法(Siamese Method),逻辑简单易实现:
- 从第一行中间位置开始填入数字1
- 每次向右上方移动一格填下一个数
- 若超出矩阵边界,循环到对面位置
- 若目标位置已被填充,就向下移动一格再填
def create_odd_magic_square(n): if n % 2 == 0: raise ValueError("n必须是奇数") # 初始化n×n的零矩阵 magic_square = [[0]*n for _ in range(n)] row, col = 0, n//2 # 起始位置:第一行中间 num = 1 while num <= n*n: magic_square[row][col] = num num += 1 # 计算右上方向的下一个位置 next_row, next_col = (row - 1) % n, (col + 1) % n # 若目标位置已有数字,改为向下移动 if magic_square[next_row][next_col] != 0: row = (row + 1) % n else: row, col = next_row, next_col return magic_square # 测试3阶幻方 print("3阶幻方:") for row in create_odd_magic_square(3): print(row)
2. 双偶阶幻方(n是4的倍数,如4、8、12...)
采用对称交换法,步骤清晰:
- 先按顺序填充1到n²的数字
- 交换每个4×4子块中对角线上的数字(替换为
n²+1-原数)
def create_double_even_magic_square(n): if n % 4 != 0: raise ValueError("n必须是4的倍数") # 按顺序填充初始矩阵 magic_square = [[i*n + j + 1 for j in range(n)] for i in range(n)] # 交换4×4子块对角线上的数字 for i in range(n): for j in range(n): if (i % 4 == j % 4) or ((i % 4) + (j % 4) == 3): magic_square[i][j] = n*n + 1 - magic_square[i][j] return magic_square # 测试4阶幻方 print("\n4阶幻方:") for row in create_double_even_magic_square(4): print(row)
3. 单偶阶幻方(n是2的倍数但不是4的倍数,如6、10、14...)
单偶阶需要拆解为四个奇数阶子幻方构造,步骤如下:
- 将n分解为
n=2m(m为奇数) - 构造四个m×m的奇数阶幻方A、B、C、D
- 对四个子幻方做数值偏移:
B=A+m²、C=A+2m²、D=A+3m² - 交换A与D的前
(m-1)//2列,交换B与C的后(m-1)//2列
def create_single_even_magic_square(n): if n % 2 != 0 or n % 4 == 0: raise ValueError("n必须是2的倍数且不是4的倍数") m = n // 2 # 构造基础的m阶奇数幻方 magic_a = create_odd_magic_square(m) # 生成偏移后的子幻方B、C、D magic_b = [[x + m*m for x in row] for row in magic_a] magic_c = [[x + 2*m*m for x in row] for row in magic_a] magic_d = [[x + 3*m*m for x in row] for row in magic_a] # 交换A和D的前(m-1)//2列 for i in range(m): for j in range((m-1)//2): magic_a[i][j], magic_d[i][j] = magic_d[i][j], magic_a[i][j] # 交换B和C的后(m-1)//2列 for i in range(m): for j in range(m - (m-1)//2, m): magic_b[i][j], magic_c[i][j] = magic_c[i][j], magic_b[i][j] # 合并四个子矩阵为最终幻方 magic_square = [] for i in range(m): magic_square.append(magic_a[i] + magic_b[i]) for i in range(m): magic_square.append(magic_c[i] + magic_d[i]) return magic_square # 测试6阶幻方 print("\n6阶幻方:") for row in create_single_even_magic_square(6): print(row)
4. 幻方验证函数
可以用以下函数验证生成的矩阵是否符合幻方要求:
def is_magic_square(matrix): n = len(matrix) if n == 0: return False # 以第一行的和为目标和 target_sum = sum(matrix[0]) # 检查每行和 for row in matrix: if sum(row) != target_sum: return False # 检查每列和 for col in range(n): col_sum = sum(matrix[row][col] for row in range(n)) if col_sum != target_sum: return False # 检查主对角线和 diag1_sum = sum(matrix[i][i] for i in range(n)) if diag1_sum != target_sum: return False # 检查副对角线和 diag2_sum = sum(matrix[i][n-1-i] for i in range(n)) if diag2_sum != target_sum: return False return True # 验证3阶幻方 print("\n3阶幻方验证结果:", is_magic_square(create_odd_magic_square(3)))
内容的提问来源于stack exchange,提问作者Mahammad Umar farooq
相关产品推荐
相关产品推荐

