幻方,有时又称魔术方阵(其简称“魔方”现一般指立方体魔术方块)或纵横图,由一组排放在正方形中的整数组成,其每行、每列以及每一条主对角线的和均相等。通常幻方由从的连续整数组成,其中为正方形的行或列的数目。因此阶幻方有列,并且所填充的数为从

洛书(九数图),朱熹《周易本义》

幻方可以使用阶方阵来表示,方阵的每行、每列以及两条对角线的和都等于常数,如果填充数为,那么有

幻方简史

《系辞》云:“河出图,洛出书,圣人则之。”在宋朝之前,洛书的记述只有文字。

九宫图实物最早发现于西汉,1977年中国考古学家在安徽阜阳县双古堆西汉古墓中发现汉文帝七年(前173年)的太乙九宫占盘,乃是中国汉代幻方的实物。东汉《数术记遗》也有记载。

后来陈抟以降认为河图洛书的洛书代表九宫图,为  个数,而 行、 列以及两对角线上各自的数之和均为15。

杨辉纵横图

 
杨辉纵横图

南宋数学家杨辉著《续古摘奇算法》把类似于九宫图图形命名为纵横图,书中列举3、4、5、6、7、8、9、10阶幻方。其中所述三阶幻方构造法:“九子斜排,上下对易,左右相更,四维挺出,戴九履一,左三右七,二四为肩,六八为足”,比法国数学家Claude Gaspar Bachet提出的方法早三百余年。

构造法

根据构造方法的不同,幻方可以分成三类:奇数阶幻方 阶幻方和 阶幻方,其中 自然数 阶幻方不存在。幻方构造法主要有:连续摆数法阶梯法(楼梯法)、奇偶数分开的菱形法对称法对角线法比例放大法斯特雷奇法LUX法拉伊尔法(基方、根方合成法)、镶边法相乘法幻方模式等。

奇数阶幻方构造法

右斜角降位法1

假设要建构n阶幻方,n为奇数。

  1. 先在第一横列中央的方格填入1。
  2. 向右上方的格子推进,依次填入2、3、4、…、n2,若超过方阵框外,则将数字填入到该横列或该直行的相对位置。
  3. 若右上方的格子已有数字,则将数字填入下面的格子中。

以下图 阶幻方为例, 填写在 (第一行第三列)的位置上; 应当填写在其右上方格即 中,由于 超出顶边界,所以从最底行进入,即  填写在 的右上方格 中; 填写在 的右上方格 中,由于 超出右边界,所以从最左列进入,即  填写在 的右上方格 中; 应该填写的方格 已经被 所占据,因此填写在 的正下方格 中;按照上面的步骤直到所有数填入。

     
     

魔方阵不是唯一的,比如5阶魔方阵还可以是:

 
 

右斜角降位法2

假设要建构n阶幻方,n为奇数。

  1. 先在第一横列中央的方格填入1。
  2. 向“右(n-1)/2格、上(n-1)/2格”的格子推进,依次填入2、3、4、…、n2,若超过方阵框外,则将数字填入到该横列或该直行的相对位置。
  3. 若右上方的格子已有数字,则将数字填入下面的格子中。

右斜角升位法

假设要建构n阶幻方,n为奇数。

  1. 先在中央格的正上方一格的方格填入1。
  2. 向右上方的格子推进,依次填入2、3、4、…、n2,若超过方阵框外,则将数字填入到该横列或该直行的相对位置。
  3. 若右上方的格子已有数字,则将数字填入上面两格的格子中。

菱形法

假设要建构n阶幻方,n为奇数。

  1. 先以对角线为两边,做一个包含n阶方阵的菱形方阵,此方阵总共有2n2-2n+1(第n个中心正方形数)个格子。
  2. 从这个菱形方阵中的最上方的尖端格子,由左上往右下,再由右上往左下,依次填入1、2、3、4、…、n2
  3. 将原先方阵上侧外的格子向下平行移动n格,填入原方阵的空格处,相同的步骤,若格子是在下侧,往上移,若格子是在左侧,往右移,若格子是在右侧,往左移。

偶数阶幻方构造法

 阶幻方构造法

消去对角线法
  1. 将1、2、3、4、…、n2由上到下、再由左到右,依次填入。
  2. 将方阵以四阶方阵为单位分割(可分割成n2个四阶方阵),然后在每个四阶方阵中,对角线上的数字擦掉。
  3. 把擦掉的数字由大的数开始,由上到下、再由左到右,依次填入。
保留对角线法

假设要建构n阶幻方,n为4的倍数。

  1. 将1、2、3、4、…、n2由上到下、再由左到右,依次填入。
  2. 将方阵以四阶方阵为单位分割(可分割成n2个四阶方阵),然后在每个四阶方阵中,不在对角线上的数字擦掉。
  3. 把擦掉的数字由大的数开始,由上到下、再由左到右,依次填入。

如4阶幻方的排列法:
 
按如上图排列好,再将非主副对角线上的各个数关于中心对调,即成下图:
 
八阶幻方构造如下
 
即:
 

 阶幻方构造法

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

例子:

[ 68  65  96  93   4   1  32  29  60  57 ]
   17L     24L      1L      8L     15L
[ 66  67  94  95   2   3  30  31  58  59 ]

[ 92  89  20  17  28  25  56  53  64  61 ]
   23L      5L      7L     14L     16L
[ 90  91  18  19  26  27  54  55  62  63 ]

[ 16  13  24  21  49  52  80  77  88  85 ]
    4L      6L     13U     20L     22L
[ 14  15  22  23  50  51  78  79  86  87 ]

[ 37  40  45  48  76  73  81  84  9   12 ]
   10U     12U     19L     21U      3U
[ 38  39  46  47  74  75  82  83  10  11 ]

[ 41  44  69  72  97  100  5  8   33  36 ]
   11X     18X     25X      2X      9X
[ 43  42  71  70  99  98   7  6   35  34 ]
斯特拉奇法

任何阶数的幻方都适用的构造法

艾歆缇雅法

此方法可用来建构任何阶数的幻方,当要建构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阶幻方。

 阶为例子,先排出 阶的幻方,如上图,再将图中每一个数都加上 ,有下图:
 

在外围加上一圈格子,把  这些数安排在外圈格子内,但要使相对两数之和等于 。对于 这些数是:  
结果如下:
 

方阵合成法

当n可以分解成两个大于等于3的正整数a与b的乘积时,此方法可由a阶幻方与b阶幻方来构造n阶幻方。

  1. 以a(k)表示a阶幻方中的每一个数字加上k*a2的结果,则所有的a(k)都是幻方,且a(0)=原本的a阶幻方。
  2. 将b阶幻方中的数字k都用幻方a(k-1)取代。

编程语言参考实现

四阶幻方全解搜索(C/C++)[1][需要较佳来源]

#include<stdio.h>
int a[17],b[17],m;
void s(int i)
{  /*搜索全部四階幻方,C代碼,運行時間7秒*/
    int n=0,j=0;
    while(++j<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&&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<17;n%4?0:printf("\n"))printf("%2d ",b[n]);
             }
             a[j]=0;
        }
}
int main(void)
{
    s(1);
    printf("四階幻方總數量:%d(含旋轉反射相同)",m);
    return 0;
}

奇数阶幻方算法的Java语言实现

/**
* @author: contribute to wikipedia according GNU
* @description:用於創建奇數階的幻方
*/

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<=n*n;count++)
          while(true)
          {
          //先x-1 y+1
        	  x--;
        	  y++;

        	  //判斷是否可以插入
          	  while(true)
                 {//循環判斷是否越界,直到一個地方不越界為止
                    //判斷是否越界:
                    //越上界x<0,則移到最下方x=x+n,y不變; continue
                   if(x<0)
                   {
                   	x += n;
                   	continue;
                   }

                   //越右界y>=n,則y=y-n,x不變;continue
                   if(y>=n)
                   {
                   	y -= n;
                   	continue;
                   }

        	    //循環判斷是否該位置已經有數據,直到找到一個空位
                      //如果有數據,則移到x = x + 2;y = y - 1; continue
                   if (y<0){y+=n;continue;}
                   if(matrix[x][y] != 0 )
                   {
                   	x += 2;y -= 1;
                   	if (x>=n){x-=n;continue;}
                   	if (y<0){y+=n;continue;}
                   	continue;
                   }
                   break;
                 }

                 //將當前的count值賦給選出的空位
                      matrix[x][y]= count;
                      break;
         }
       }

       public static void print()
       {
        	for(int i = 0; i < n; i++)
        	{
        		for(int j = 0; j < 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

 阶幻方算法的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 < n; i++)
 		  for(int j = 0; j < n; j++)
 			  matrix[i][j] = ++ini;
 		
 	  //輸出對調前的樣子
 	  System.out.println("對調之前的樣子:");
 	  print();
 	
 	  //然後對調(僅對右上方的數進行遍歷)
 	  for(int i = 0; i < n; i++)
 	      for(int j = i + 1; j < n; j++)
 	      {
 	    	  if(( i != j) && (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 < n; i++)
 		{
 			for(int j = 0; j < 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_

研究价值

知名华人数学家陈省身曾在数学演讲中说幻方只是一个奇迹,它在数学中没有引起更普遍深刻的影响,不属于“好的数学”。[2]

对幻方的学习和研究一直局限于趣味数学本身,更接近数字游戏或文字游戏,缺乏与主流数学的联系(和璇玑图在中国诗歌中的地位有一些相似)。数学和物理中也有具有更多学术价值的特殊数字方阵,如推动了试验设计研究的拉丁方阵和已有应用的阿达玛矩阵,还有在量子力学中有重要价值的泡利矩阵及其推广版本盖尔曼矩阵魔术方块则可以与群论建立联系(见魔方群),可以作为抽象代数的入门教具,也是计算群论的研究案例之一,并非单纯的几何玩具。高性能的计算机诞生后,幻方、幻星、素数环(prime ring problem)等很多这类需要满足特殊规律的填数问题,只要所需的数字规模不大,都可以考虑通过深度优先搜索算法暴力求解和枚举。

艺术与流行文化

  • 德国画家与雕刻家阿尔布雷希特·丢勒曾在一幅名作《忧郁》(Melencolia I)的角落中画下一个幻方。这个著名的幻方图也被知名工程数学软件MATLAB加入自己的帮助文档中。[来源请求]

参见

参考资料

引用

  1. ^ "所有四阶幻方". [2017-01-11]. (原始内容存档于2017-01-13) (中文(中国大陆)). 
  2. ^ 黄且圆. 陈省身:如何做“好的数学”. 2015年3月2日 [2019年9月29日]. (原始内容存档于2019年9月29日) (中文(中国大陆)). 可惜幻方只是一个奇迹,它在数学中没有引起其他更普遍深刻的影响。相反地,另外一个奇迹,所有的圆、圆的周长和它的直径之比都是一个不变的数,数学上称之为圆周率,记作。这个结果可重要了,因为这个数渗透了整个数学!...幻方只是一个偶然现象,虽很巧妙,但不属于好的数学。  |journal=被忽略 (帮助)

延伸阅读

  • 高治源. 九宫图探秘. 香港天马图书有限公司. 2004 (中文(香港)). 
  • 张道鑫. 素数幻方. 香港天马图书有限公司. 2003 (中文(香港)). 
  • 李杭强. 趣味数学幻方. 香港天马图书有限公司. 2002 (中文(香港)). 
  • 林正禄. 开拓智力的奇方——幻方. 香港天马图书有限公司. 2001 (中文(香港)). 

外部链接