大家好,欢迎来到IT知识分享网。
五阶幻方探讨
因前面计算了四阶幻方(详见《四阶幻方知多少》一文),也就引起了对五阶幻方的性趣。以当前对幻方的认知,要能保证不遗漏、不重复的找完就自然是走基数组——穷举法之路。
基数组:首先,在1~25个自然数中取5个不同的数为一组,使5个数相加等于幻和65,再以这样的数组为单位来构建幻方。那么这样的排列有多少个?经计算有个。为了便于叙述方便,将这个排列称为基数组。
一、简单直接法:
A11 |
A12 |
A13 |
A14 |
A15 |
A21 |
A22 |
A23 |
A24 |
A25 |
A31 |
A32 |
A33 |
A34 |
A35 |
A41 |
A42 |
A43 |
A44 |
A45 |
A51 |
A52 |
A53 |
A54 |
A55 |
假定所填写幻方形式如下:A23代表第2行第3列的数字,其余相同。从基数组中取一组数,依次定为A11、A21、A31、A41、A51。即A11+A21+A31+A41+A51=65,定为第一列;再从基数组中取四组B1、B2、B3、B4、B5;C1、C2、C3、C4、C5;D1、D2、D3、D4、D5;E1、E2、E3、E4、E5;F1、F2、F3、F4、F5。但B1=A11,C1=A21,D1=A31,E1=A41,
A11/B1 |
B2 |
B3 |
B4 |
B5 |
A21/C1 |
C2 |
C3 |
C4 |
C5 |
A31/D1 |
D2 |
D3 |
D4 |
D5 |
A41/E1 |
E2 |
E3 |
E4 |
E5 |
A51/F1 |
F2 |
F3 |
F4 |
F5 |
F1=A51且各数字也不能相同,依次确定为二、三、四、五行,这样这个数字方阵中每行的数字相加等于65,第一列也等于65,但第2、3、4、5列,两对角线的数字相加是否等于65?就要去计算、判断了。这样就将循环嵌套的层级数降到了最低。但逐一地抽取、逐一地排除。尽管是用计算机,时间也要很长的,因有大量的无效循环,每个数组的循环次数是以千为单位计算。编程最简单、时间太长,不可取。
二、直接、筛选法
可理解为对第一种方法的升级,即每一数组都以前面的数组为依据进行筛选拦截。如第一个数组除了A1要受约束外,对其余各数中凡是有与前面出现的数字相同的予以删除,这样余下的数组中还有约三千个左右;第二组则以一、二组为据进行筛选,依次类推,最后第五组约还有几百个左右。这种方法比第一种好一点,但用时仍然很长,不可取。
- 对角线法
A1/C1 |
C2 |
C3 |
C4 |
B5/C5 |
D1 |
A2/D2 |
D3 |
B4/D4 |
D5 |
E1 |
E2 |
A3/B3/E3 |
E4 |
E5 |
F1 |
B2/F2 |
F3 |
A4/F4 |
F5 |
B1/G1 |
G2 |
G3 |
G4 |
A5/G5 |
即首先将第一组数确定为主对角线,再以A3为条件选择确定第二组数为副对角线。这样对角线符合要求,再以两对角线上的数为约束条件、采用层层筛选确定后面各组的数据。这种方法又要好一点,但运算仍然很慢,因各组的循环次数还是很高。不能尽早排除掉一些无效循环,要提高效率就是要减少循环、嵌套的层级和次数。
四、直接约束筛选法
A1/B1/D1 |
B2 |
B3 |
B4 |
B5/C5 |
A2/E1 |
D2/E2 |
E3 |
C4/E4 |
E5 |
A3/F1 |
F2 |
C3/D3/F3 |
F4 |
F5 |
A4 |
C2 |
D4 |
||
A5/C1 |
D5 |
可理解为对前面三种方法的综合应用,用以出现了的数字为准对后面的基数组进行筛选。1、确定第一列A1、A2、A3、A4、A5,与第一行B1、B2、B3、B4、B5,其方法与直接筛选法相同;2、确定副对线上的数,因副对角线上的数已出现两个(A5、B5),因此副对角线上的自由变量就只有三个了,再排除掉前面已经出现了的数字,其循环量就在百位左右了;3、同样主对角线的数字也已出现了两个(A1、C3),应优先确定主对角线(因对角线上的数字涉及到纵、横、斜三个方面),其循环量下降到了两位数,4、计算第二行,此时第二行已出现三个数字A2、D2、C4。5、计算第三行,第三行也出现了A3、C3。
后面的第四行、第五行还有5个数未确定。对这5个数不再采用数组方式来确定,一方面是为了降低循环嵌套层级,另方面要排除掉与前面出现的数据相同所用的时间也较长,转而采用后面计算排除,用时还少些。
这样做在编程上要复杂点,层层筛选,层层约束,但尽可能的将一些无效循环及早淘汰掉了,所以看起来程序还要长一些,但运算反而还快点。前面的三种方法编程上很简单,但不能及早淘汰掉一些无效循环,而本身循环量又大,所以导致整体速度下降。
程序简单不一定就好。
通过实践、分析发现:循环嵌套层级数越多,运算速度就会下降得多;一个循环数组中受约束的数字越多(自由变量就越少)循环量就越少;幻方中对角线上的数与纵、横、斜都相关,因此在可能的情况下要优先确定,这样可以将一些无效循环及早消除掉,大幅减少后面的计算量。
经计算:
以个基数组中的第一个数组(第一个数组:1、2、13、24、25,即每个幻方的第一列都是这5个数)为准的五阶幻方的总数为8205个。
用时:近80小时(79小时42分51秒)
根据四阶幻方的情况看,以数字1开头(幻方左上角第一个数字)的幻方数量不比其它数字开头的多,来推断:五阶幻方的个数应在14亿~15亿了。
还可以以基数组为据,进一步构造9位数组、12位数组和米字型等。
这些看起来是减少了循环嵌套层级,但实际上是将循环嵌套层级进行了分散处理。以9位数组为例,构造9位数组时就有很大的循环量,而且所用空间也不少(80G以上),用一个数据表还装不下(我是为了便于后面使用方便,用了25个数据表),用了几个小时才做完这一步。而且在最后填写时循环量一点未减少,也不能及早淘汰掉无效循环。所以速度反而慢了很多。对电脑的内存、硬盘空间要求更大。
A1/B9/C1 |
A2 |
A3 |
A4 |
A5/B1 |
C2 |
B8 |
A6 |
B2 |
|
C3 |
A7/B7 |
B3 |
||
C4 |
A8 |
B6 |
B4 |
|
A9/C5 |
C6 |
C7 |
C8 |
B5/C9 |
9位数组填写顺序:
A1/B1 |
A2/B2 |
A3/B3 |
A4/B4 |
A5/B5 |
A12 |
B12 |
A6 |
B6 |
|
A11 |
A7/B11 |
B7 |
||
A10 |
A8 |
B10 |
B8 |
|
A9 |
B9 |
12位数组填写顺序:
A2 |
A14 |
A9 |
||
A3 |
A15 |
A8 |
||
A10 |
A11 |
A1 |
A12 |
A13 |
A7 |
A16 |
A4 |
||
A6 |
A17 |
A5 |
米字型数组:
当然,编程中必要的技能技巧是必须的,以计算基数组为例,三阶幻方、四阶幻方的基数组计算有无技巧都无所谓,很快出结果;但随着阶数的提高,问题就出来了,以七阶为例,沿用三阶四阶的算法,算了十多个小时遥遥无期,后改为分段计算用了百多个小时才算出结果,后经改变算法、优化程序也用了近40小时。
三阶幻方基数组个数:48个
四阶幻方基数组个数:2064个
五阶幻方基数组个数:个
六阶幻方基数组个数:个
七阶幻方基数组个数:个
三阶幻方全部只有8个。
四阶幻方全部只有7040个。
五阶幻方只算了约1/,就达8205个。
这个增长幅度也是惊人的!
以目前对幻方的认知及所使用的算法来看,如果说对5阶幻方还可以试一下,对6阶以上就真成了可望不可及了(循环量、嵌套层级都是比五阶的多得多,比基数组个数都可比较,我的电脑只能是理论上行而实际上不行,到时电脑是否会崩溃?)。
附:本人编程计算所使用的计算机及程序语言。
联想台式机Lenovo 510。处理器Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz;内存:8G(机带);系统平台:Windos 10 专业版,64 位操作系统, 基于 x64 的处理器。
编程软件:Microsoft Visual FoxPro 9.0。
欢迎斧正、讨论:
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/143966.html