下午偶然从MATLAB上找到了构造幻方的源代码,是用MATLAB程序设计语言实现的(基于C语言设计),可以生成阶数不限的幻方。下午把此算法用批处理实现了。下面附上批版代码以及magic(n)函数源代码。- @echo off
- :begin
- setlocal enabledelayedexpansion
- set rank=
- echo.&set /p "rank=请输入幻方阶数:"
- set /a remainder=rank%%2
- if !remainder! equ 1 (
- call :odd !rank!
- ) else (
- set /a remainder=rank%%4
- if !remainder! equ 0 (
- call :even_4
- ) else call :even_2
- )
-
- rem --------------奇数阶幻方------------------
-
- :odd
- set rank=%1
- call :create
- for /l %%i in (1 1 !rank!) do (
- for /l %%j in (1 1 !rank!) do (
- set /a $%%i%%j="(.%%i%%j+.%%j%%i-(rank+3)/2+rank)%%rank"
- set /a #%%i%%j="(.%%i%%j+.%%j%%i*2-2+rank)%%rank"
- set /a _%%i%%j="rank*$%%i%%j+#%%i%%j+1"
- )
- )
- if not "%~2" equ "" goto :eof
- call :output
- endlocal&goto :begin
-
- rem -------------偶数阶幻方(4整除)---------------
-
- :even_4
- call :create
- set num=0
- for /l %%i in (1 1 !rank!) do (
- for /l %%j in (1 1 !rank!) do (
- set /a "a=(.%%i%%j%%4)/2,b=(.%%j%%i%%4)/2"
- if !a! equ !b! ( set "_%%i%%j=1" ) else set "_%%i%%j=0"
- set /a "num+=1,n=rank*rank+1"
- set /a #%%i%%j=!num!
- if !_%%i%%j! equ 1 (set /a _%%i%%j=n-#%%i%%j) else set _%%i%%j=!#%%i%%j!
- )
- )
- call :output
- endlocal&goto :begin
-
- rem --------------偶数阶幻方(2整除)--------------
-
- :even_2
- set /a p=rank/2,q=rank,p1=p+1
- call :odd !p! OK
- set rank=!q!
- call :rearrange 1 !p! !p1! !rank! 2
- call :rearrange !p1! !rank! 1 !p! 3
- call :rearrange !p1! !rank! !p1! !rank! 1
- call :transpos !p!
- if !rank! equ 2 (
- call :output
- endlocal&goto :begin
- )
- for /l %%i in (1 1 !p!) do set "var_i=!var_i! %%i"
- set /a k=(rank-2)/4,m=rank-k+2
- for /l %%i in (1 1 !k!) do set "var_j=!var_j! %%i"
- for /l %%i in (!m! 1 !rank!) do set "var_j=!var_j! %%i"
- call :exchange "!var_i!" "!var_j!"
- set /a i=k+1
- set "j=1 !i!"
- call :exchange "!i!" "!j!"
- call :output
- set i=
- set j=
- set var_i=
- set var_j=
- endlocal&goto :begin
-
-
- rem -------------以下为子函数-----------------
-
- :create
- set /a rank_2=rank*rank,i=1,j=1
- for /l %%i in (1 1 !rank_2!) do (
- set .!i!!j!=!j!
- set /a j+=1
- if !j! gtr !rank! set j=1&set /a i+=1
- )
- goto :eof
-
- :output
- call :append !rank!
- for /l %%i in (1 1 !rank!) do (
- for /l %%j in (1 1 !rank!) do set result=!result! !_%%i%%j:~-3!
- echo.!result!&set result=
- )
- goto :eof
-
- :rearrange
- set /a p2=%5*p*p,i=1,j=1
- for /l %%i in (%1 1 %2) do (
- for /l %%j in (%3 1 %4) do (
- set /a _%%i%%j=_!j!!i!+p2
- set /a j+=1
- )
- set /a "i+=1,j=1"
- )
- goto :eof
-
- :exchange
- for %%i in (%~1) do (
- for %%j in (%~2) do (
- set /a i=%%i+p
- set tmp=!_%%i%%j!
- call set _%%i%%j=%%_!i!%%j%%
- set _!i!%%j=!tmp!
- )
- )
- goto :eof
-
- :transpos
- for /l %%i in (1 1 %1) do (
- for /l %%j in (%%i 1 %1) do (
- if not %%i equ %%j (
- set tmp=!_%%i%%j!
- set _%%i%%j=!_%%j%%i!
- set _%%j%%i=!tmp!
- )
- )
- )
- goto :eof
-
- :append
- for /l %%i in (1 1 %1) do (
- for /l %%j in (1 1 %1) do (
- set "_%%i%%j= !_%%i%%j!"
- )
- )
- goto :eof
复制代码 函数magic(n);
function M = magic(n)
%MAGIC Magic square.
% MAGIC(N) is an N-by-N matrix constructed from the integers
% 1 through N^2 with equal row, column, and diagonal sums.
% Produces valid magic squares for all N > 0 except N = 2.
% Copyright 1984-2002 The MathWorks, Inc.
% $Revision: 5.15 $ $Date: 2002/04/15 03:44:23 $
% Historically, MATLAB's magic was a built-in function.
% This M-file uses a new algorithm to generate the same matrices.
n = floor(real(double(n(1))));
% Odd order.
if mod(n,2) == 1
[J,I] = meshgrid(1:n);
A = mod(I+J-(n+3)/2,n);
B = mod(I+2*J-2,n);
M = n*A + B + 1;
% Doubly even order.
elseif mod(n,4) == 0
[J,I] = meshgrid(1:n);
K = fix(mod(I,4)/2) == fix(mod(J,4)/2);
M = reshape(1:n*n,n,n)';
M(K) = n*n+1 - M(K);
% Singly even order.
else
p = n/2;
M = magic(p);
M = [M M+2*p^2; M+3*p^2 M+p^2];
if n == 2, return, end
i = (1:p)';
k = (n-2)/4;
j = [1:k (n-k+2):n];
M([i; i+p],j) = M([i+p; i],j);
i = k+1;
j = [1 i];
M([i; i+p],j) = M([i+p; i],j);
end
分三种情况,奇数、偶数、双偶数。MATLAB源代码中调用了一些函数,可以在帮助文档中找到。
附:
在MATLAB软件环境下用命令调用magic(n),效率很高,上千阶的幻方也只需要2-3秒;可用批实现的代码效率却不尽如人意,比上面几楼各位的代码还要低些,可能是大量的变量赋值运算影响了效率吧;大家再来优化下代码,看哪里还有提升的空间。 |