算法:摘自《组合数学》屈婉玲编北京大学出版社出版1989.11,2014年1月15次印刷
设n为奇数,用下面的方法构造n阶幻方:
1、a=1, x=1, y=(n+1)/2
2、若a = n*n +1则算法结束,否则把a填入(x, y)的方格。
3、若x=1且y=n,则x=x+1, a=a+1转2
4、x=1且y!=n,则x=n, y=y+1, a=a+1转2
5、若x!=1且y=n,则x=x-1, y=1, a=a+1转2
6、若(x-1, y+1)的方格为空,则x=x-1,y=y+1, a=a+1转2
7、若(x-1, y+1)的方格不为空, 则x=x+1,a=a+1转2
附python代码:
import numpy as np
def magic_square(n: int):
# n为奇数
a = 1
x = 1
y = int((n + 1) / 2)
arrayn = np.zeros((n, n), int)
while 1:
if a == n ** 2 + 1:
break
else:
# print(a, x, y)
arrayn[x-1, y-1] = a
if (x == 1) and (y == n):
x += 1
a += 1
elif (x == 1) and (y != n):
x = n
y += 1
a += 1
elif (x != 1) and (y == n):
x -= 1
y = 1
a += 1
elif arrayn[x - 2, y] == 0:
x -= 1
y += 1
a += 1
elif arrayn[x - 2, y] != 0:
x += 1
a += 1
return arrayn
def magic_check(array: np.array):
a, b = array.shape
assert a == b
sum_line = array[0, :].sum()
diagonal = 0
diagonal_reverse = 0
for i in range(a):
assert array[i, :].sum() == sum_line
assert array[:, i].sum() == sum_line
diagonal += array[i, i]
diagonal_reverse += array[a-i-1, i]
assert diagonal == sum_line
print(sum_line)
a_3 = magic_square(7)
print(a_3)
magic_check(a_3)
其中magic_square构建幻方,n为阶数
magic_check验证结果。
15阶幻方是这样的。
[[122 139 156 173 190 207 224 1 18 35 52 69 86 103 120]
[138 155 172 189 206 223 15 17 34 51 68 85 102 119 121]
[154 171 188 205 222 14 16 33 50 67 84 101 118 135 137]
[170 187 204 221 13 30 32 49 66 83 100 117 134 136 153]
[186 203 220 12 29 31 48 65 82 99 116 133 150 152 169]
[202 219 11 28 45 47 64 81 98 115 132 149 151 168 185]
[218 10 27 44 46 63 80 97 114 131 148 165 167 184 201]
[ 9 26 43 60 62 79 96 113 130 147 164 166 183 200 217]
[ 25 42 59 61 78 95 112 129 146 163 180 182 199 216 8]
[ 41 58 75 77 94 111 128 145 162 179 181 198 215 7 24]
[ 57 74 76 93 110 127 144 161 178 195 197 214 6 23 40]
[ 73 90 92 109 126 143 160 177 194 196 213 5 22 39 56]
[ 89 91 108 125 142 159 176 193 210 212 4 21 38 55 72]
[105 107 124 141 158 175 192 209 211 3 20 37 54 71 88]
[106 123 140 157 174 191 208 225 2 19 36 53 70 87 104]]
|