幻方

幻方，有时又称魔术方阵（其简称“魔方”现一般指立方体的魔术方块）或纵横图，由一组排放在正方形中的整数组成，其每行、每列以及每一条主对角线的和均相等。通常幻方由从formula_1到formula_2的连续整数组成，其中formula_3为正方形的行或列的数目。因此formula_3阶幻方有formula_3行formula_3列，并且所填充的数为从formula_1到formula_2。
幻方可以使用formula_3阶方阵来表示，方阵的每行、每列以及两条对角线的和都等于常数formula_10，如果填充数为formula_11，那么有
幻方简史.
《系辞》云：「河出图，洛出书，圣人则之。」在宋朝之前，洛书的记述只有文字。
九宫图实物最早发现于西汉，1977年中国考古学家在安徽阜阳县双古堆西汉古墓中发现汉文帝七年（前173年）的太乙九宫占盘，乃是中国汉代幻方的实物。东汉《数术记遗》也有记载。
后来陈抟以降认为河图洛书的洛书代表九宫图，为formula_13这formula_14个数，而formula_15行、formula_15列以及两对角线上各自的数之和均为15。
杨辉纵横图.
南宋数学家杨辉著《续古摘奇算法》把类似于九宫图的图形命名为纵横图，书中列举3、4、5、6、7、8、9、10阶幻方。其中所述三阶幻方构造法：“九子斜排，上下对易，左右相更，四维挺出，戴九履一，左三右七，二四为肩，六八为足”，比法国数学家Claude Gaspar Bachet提出的方法早三百余年。
构造法.
根据构造方法的不同，幻方可以分成三类：奇数阶幻方、formula_17阶幻方和formula_18阶幻方，其中formula_19为自然数，formula_20阶幻方不存在。幻方构造法主要有：连续摆数法、阶梯法（楼梯法）、奇偶数分开的菱形法、对称法、对角线法、比例放大法、斯特雷奇法、LUX法、拉伊尔法（基方、根方合成法）、镶边法、相乘法、幻方模式等。
奇数阶幻方构造法.
右斜角降位法1.
假设要建构n阶幻方，n为奇数。
以下图formula_21阶幻方为例，formula_1填写在formula_23（第一行第三列）的位置上；formula_20应当填写在其右上方格即formula_25中，由于formula_25超出顶边界，所以从最底行进入，即formula_27；formula_15填写在formula_27的右上方格formula_30中；formula_31填写在formula_30的右上方格formula_33中，由于formula_33超出右边界，所以从最左列进入，即formula_35；formula_21填写在formula_35的右上方格formula_38中；formula_39应该填写的方格formula_23已经被formula_1所占据，因此填写在formula_38的正下方格formula_43中；按照上面的步骤直到所有数填入。
魔方阵不是唯一的，比如5阶魔方阵还可以是：
右斜角降位法2.
假设要建构n阶幻方，n为奇数。
右斜角升位法.
假设要建构n阶幻方，n为奇数。
菱形法.
假设要建构n阶幻方，n为奇数。
偶数阶幻方构造法.
4k阶幻方构造法.
保留对角线法.
假设要建构n阶幻方，n为4的倍数。
如4阶幻方的排列法：
formula_44
按如上图排列好，再将非主副对角线上的各个数关于中心对调，即成下图：
formula_45
八阶幻方构造如下
formula_46
即：
formula_47
4k+2阶幻方构造法.
LUX法.
在(4M+2)×(4M+2）个方格的适当格点上，先排出2M+1阶的幻方。在前M+1行的格点，全部标上「L」；在第M+1行的中间格点标上「U」，其余格点标上「L」；在第M+2行的中间格点标上「L」，其余格点标上「U」；在余下的M-1行的格点全部标上「X」。将格点上的数乘以4再减4，再按下面的规则加上1至4其中一个数，填入对应的格上：
 4 1 1 4 1 4
 L U X
 2 3 2 3 3 2
例子：
任何阶数的幻方都适用的构造法.
艾歆缇雅法.
此方法可用来建构任何阶数的幻方，当要建构n阶幻方时，使用两个方阵，一个填入正整数1到n各n次，另一个则填入0、n、2n、3n、…、(n-1)*n各n次，尽管奇数阶幻方与偶数阶幻方的填入方式有所不同。
对于奇数阶幻方：
第一个方阵：在第一横列中央的方格填入1，并且往左下角不断填入1，若超出方阵外，则向右平移n格，直到每一横列都有一个方格填入1为止，再把所有填入1的方格右边的格子填入2（若超出方阵外，则向左平移n格），再把所有填入2的方格右边的格子填入3，一直到填入n为止。
第二个方阵：在第一直行中央的方格填入0，并且往右下角不断填入1，若超出方阵外，则向上平移n格，直到每一直行都有一个方格填入0为止，再把所有填入0的方格右边的格子填入n（若超出方阵外，则向上平移n格）。再把所有填入n的方格右边的格子填入2n，一直到填入(n-1)*n为止。
再把两个方阵中的数相加。
事实上，你可以将这两个方阵中的每一个相同数字都替换为另一个数字，只要这两个方阵中原本有出现的n个数字都仍然各出现n次即可，唯一的条件是第一个方阵中(n+1)/2这个数字，以及第二个方阵中(n-1)*n/2这个数字，不能被替换。
对于偶数阶幻方：
第一个方阵：第一直行由上到下依次填入1到n，第二直行由下到上依次填入1到n，第三直行与第二直行相同，第四直行与第一直行相同，若超过四直行，则重复第一到第四直行的步骤。
第二个方阵：第一横列由上到下依次填入0到n*(n-1)，第二横列由下到上依次填入0到n*(n-1)，第三横列与第二横列相同，第四横列与第一横列相同，若超过四横列，则重复第一到第四横列的步骤。
此方法暂时只适用于4k阶的幻方。
事实上，你可以将这两个方阵中的每一个相同数字都替换为另一个数字，只要这两个方阵中原本有出现的n个数字都仍然各出现n次即可，唯一的条件是第一个方阵中每个直行相对的两个数字之和必须是n+1，以及第二个方阵中每个横列相对的两个数字之和必须是n*(n-1)。
如果是4k+2阶的幻方，就必须在第二个方阵中，检查每个直行相对的两个数字之和为n*(n-1)的格子，对于这些格子，第一个方阵的对应格子。
加边法.
当n为大于等于5的正整数时，此方法可由n-2阶幻方外围加上一圈来构造n阶幻方。
以formula_39阶为例子，先排出formula_31阶的幻方，如上图，再将图中每一个数都加上formula_50，有下图：
formula_51
在外围加上一圈格子，把formula_52和formula_53这些数安排在外圈格子内，但要使相对两数之和等于formula_54。对于formula_55这些数是：formula_56；formula_57。结果如下：
formula_58
方阵合成法.
当n可以分解成两个大于等于3的正整数a与b的乘积时，此方法可由a阶幻方与b阶幻方来构造n阶幻方。
编程语言参考实现.
四阶幻方全解搜索(C/C++).
int a[17],b[17],m;
void s(int i)
 int n=0,j=0;
 while(++j&lt;17)
 if(!a[j])
 a[b[i]=j]=1;
 switch(i)
 case 1:case 2:case 3:case 5:case 6:case 7:case 9:case 10:s(i+1);break;
 case 11:if(b[6]+b[7]+b[10]+b[11]==34)s(12);break;
 case 4:case 8:case 12:if(b[i-3]+b[i-2]+b[i-1]+b[i]==34)s(i+1);break;
 case 13:if(b[1]+b[5]+b[9]+b[13]==34&amp;&amp;b[4]+b[7]+b[10]+b[13]==34)s(14);break;
 case 14:case 15:if(b[i-12]+b[i-8]+b[i-4]+b[i]==34)s(i+1);break;
 case 16:for(printf("\n"),++m;++n&lt;17;n%4?0:printf("\n"))printf("%2d ",b[n]);
 a[j]=0;
int main(void)
 s(1);
 printf("四阶幻方总数量:%d(含旋转反射相同)",m);
 return 0;
奇数阶幻方算法的Java语言实现.
public class magic_squre_odd {
 static int[][] matrix;
 static int n;
 public static void magic_squre_odd_generate()
 { matrix = new int[n][n];
 //所有的数初始化为0
 matrix[0][(n-1)/2] = 1;
 int x = 0,y = (n-1)/2;
 //count:记住已经插入过的数
 for(int count = 2; count&lt;=n*n;count++)
 while(true)
 //先x-1 y+1
 x--;
 y++;
 //判断是否可以插入
 while(true)
 {//循环判断是否越界，直到一个地方不越界为止
 //判断是否越界：
 //越上界x&lt;0，则移到最下方x=x+n，y不变; continue
 if(x&lt;0)
 x += n;
 continue;
 //越右界y&gt;=n，则y=y-n，x不变;continue
 if(y&gt;=n)
 y -= n;
 continue;
 //循环判断是否该位置已经有数据，直到找到一个空位
 //如果有数据，则移到x = x + 2;y = y - 1; continue
 if(matrix[x][y] != 0 )
 x += 2;y -= 1;
 continue;
 break;
 //将当前的count值赋给选出的空位
 matrix[x][y]= count;
 break;
 public static void print()
 for(int i = 0; i &lt; n; i++)
 for(int j = 0; j &lt; n; j++)
 //System.out.println(matrix[i][j]);
 System.out.print(matrix[i][j]);
 System.out.print("_");
 System.out.println();
 public static void main(String[] args)
 { //手工输入n的值，并确保为奇数
 n = 11;
 magic_squre_odd_generate();
 print();
以下是本算法将n设置为11时得出的11阶幻方的构造结果：
 68 81 94 107 120 1 14 27 40 53 66
 80 93 106 119 11 13 26 39 52 65 67
 92 105 118 10 12 25 38 51 64 77 79
 104 117 9 22 24 37 50 63 76 78 91
 116 8 21 23 36 49 62 75 88 90 103
 7 20 33 35 48 61 74 87 89 102 115
 19 32 34 47 60 73 86 99 101 114 6
 31 44 46 59 72 85 98 100 113 5 18
 43 45 58 71 84 97 110 112 4 17 30
 55 57 70 83 96 109 111 3 16 29 42
 56 69 82 95 108 121 2 15 28 41 54
4阶幻方算法的Java语言实现.
 * @author: contribute to wikipedia according GNU
 * @description:用于创建4阶的幻方
 */
 public class magic_square_4m {
 * @param args
 static int matrix[][];
 static int n;
 static void magic_squre_4m_generate()
 //初始化matrix
 matrix = new int[n][n];
 //将matrix里的位置用数顺序排列
 int ini = 0;
 for(int i = 0; i &lt; n; i++)
 for(int j = 0; j &lt; n; j++)
 matrix[i][j] = ++ini;
 //输出对调前的样子
 System.out.println("对调之前的样子：");
 print();
 //然后对调（仅对右上方的数进行遍历）
 for(int i = 0; i &lt; n; i++)
 for(int j = i + 1; j &lt; n; j++)
 if(( i != j) &amp;&amp; (i + j) != (n -1) )
 { //对不在主付对角线上的数关于中心对调
 int temp;
 temp = matrix[i][j];
 matrix[i][j] = matrix[n -1 - i][n - 1 - j];
 matrix[n -1 - i][n - 1 - j] = temp;
 
 public static void print()
 for(int i = 0; i &lt; n; i++)
 for(int j = 0; j &lt; n; j++)
 System.out.print(matrix[i][j]);
 System.out.print("_");
 System.out.print("\n");
 public static void main(String[] args) {
 //这里手动设置n的数值为4，这里只能设置为4，因为只求4阶幻方 
 n = 4;
 magic_squre_4m_generate();
 System.out.println("对调之后的样子：");
 print();
以下是本算法输出的结果：
 对调之前的样子：
 1_2_3_4_
 5_6_7_8_
 9_10_11_12_
 13_14_15_16_
 对调之后的样子：
 1_15_14_4_
 12_6_7_9_
 8_10_11_5_
 13_3_2_16_
研究价值.
知名华人数学家陈省身曾在数学演讲中说幻方只是一个奇迹，它在数学中没有引起更普遍深刻的影响，不属于“好的数学”。
对幻方的学习和研究一直局限于趣味数学本身，更接近数字游戏或文字游戏，缺乏与主流数学的联系(和璇玑图在中国诗歌中的地位有一些相似)。数学和物理中也有具有更多学术价值的特殊数字方阵，如推动了试验设计研究的拉丁方阵和已有应用的阿达玛矩阵，还有在量子力学中有重要价值的泡利矩阵及其推广版本盖尔曼矩阵。魔术方块则可以与群论建立联系(见魔方群)，可以作为抽象代数的入门教具，也是计算群论的研究案例之一，并非单纯的几何玩具。高性能的计算机诞生后，幻方、幻星、素数环(prime ring problem)等很多这类需要满足特殊规律的填数问题，只要所需的数字规模不大，都可以考虑通过深度优先搜索算法暴力求解和枚举。