如何编写Python代码实现随用户输入生成不同的幻方矩阵?
幻方矩阵相同输入输出重复的解决方法
你的代码采用标准Siamese算法生成奇数阶幻方,由于起始位置固定(行索引n//2,列索引n-1),所以每次输入相同的n都会得到完全一致的幻方。要实现相同输入输出不同合法幻方,可以利用幻方的等价变换特性——旋转、翻转后的矩阵依然是幻方,或者随机调整起始位置生成不同基础幻方。
方案1:对基础幻方进行随机等价变换
先通过原算法生成一个基础幻方,再随机对其进行旋转、翻转等操作,这些操作不会破坏幻方的行、列、对角线和相等的性质。
修改后的代码示例:
import random def generate_base_magic_square(n): m = [[0 for x in range(n)]for y in range(n)] i = n // 2 j = n - 1 num = 1 while num <= (n * n): if i == -1 and j == n: j = n - 2 i = 0 else: if j == n: j = 0 if i < 0: i = n - 1 if m[int(i)][int(j)]: j = j - 2 i = i + 1 continue else: m[int(i)][int(j)] = num num = num + 1 j = j + 1 i = i - 1 return m def rotate_matrix(matrix): # 顺时针旋转90度 n = len(matrix) return [[matrix[n-j-1][i] for j in range(n)] for i in range(n)] def flip_matrix(matrix): # 水平翻转 return [row[::-1] for row in matrix] def generate_randomized_magic_square(n): base_square = generate_base_magic_square(n) # 随机选择变换组合:原矩阵、旋转90/180/270度、水平翻转 transformations = [ lambda x: x, rotate_matrix, lambda x: rotate_matrix(rotate_matrix(x)), lambda x: rotate_matrix(rotate_matrix(rotate_matrix(x))), flip_matrix ] # 随机应用一种变换 transform = random.choice(transformations) return transform(base_square) def print_magic_square(square): n = len(square) print(f"每行、每列及对角线元素之和: {int(n*(n*n+1)/2)}") for row in square: print(' '.join(f'%2d' % num for num in row)) n = int(input("请输入矩阵的阶数(奇数): ")) if n % 2 == 0: print("注:当前算法仅支持奇数阶幻方") else: magic_square = generate_randomized_magic_square(n) print_magic_square(magic_square)
方案说明
- 将原代码拆分为生成基础幻方、变换矩阵、打印三个独立函数,便于维护和扩展
- 提供5种基础等价变换(旋转0/90/180/270度、水平翻转),每次运行随机选择一种,生成不同合法幻方
- 可扩展更多变换(如垂直翻转、翻转后再旋转),进一步提升随机性
方案2:随机化Siamese算法的起始位置
Siamese算法的起始位置并非唯一,对于奇数阶幻方,可随机选择起始点并调整算法逻辑,直接生成不同的基础幻方。
修改后的代码示例:
import random def generate_random_start_magic_square(n): m = [[0 for x in range(n)]for y in range(n)] # 随机选择起始行和列 i = random.randint(0, n-1) j = random.randint(0, n-1) start_i, start_j = i, j num = 1 while num <= (n * n): if m[i][j] != 0: # 冲突时回到初始位置的下一行,重新开始填充 i = (start_i + 1) % n j = start_j start_i = i # 极端冲突情况(概率极低),递归重新生成 if m[i][j] != 0: return generate_random_start_magic_square(n) m[i][j] = num num += 1 # 按Siamese规则移动:行减1,列加1,超出边界则循环 i = (i - 1) % n j = (j + 1) % n return m def print_magic_square(square): n = len(square) print(f"每行、每列及对角线元素之和: {int(n*(n*n+1)/2)}") for row in square: print(' '.join(f'%2d' % num for num in row)) n = int(input("请输入矩阵的阶数(奇数): ")) if n % 2 == 0: print("注:当前算法仅支持奇数阶幻方") else: magic_square = generate_random_start_magic_square(n) print_magic_square(magic_square)
方案说明
- 随机选择起始位置,当填充遇到冲突时,调整到初始位置的下一行重新开始
- 极端冲突情况会自动递归重新生成,保证输出合法幻方
- 直接生成不同结构的基础幻方,而非依赖对已有幻方的变换
内容的提问来源于stack exchange,提问作者SABIH SHAFI
相关产品推荐
相关产品推荐

