Mr.*_*ard 7 wolfram-mathematica matrix fill
我想以n * n
下列方式填充(n为奇数)矩阵:
_ _ _ 23 22 21 20
_ _ 24 10 9 8 37
_ 25 11 3 2 19 36
26 12 4 1 7 18 35
27 13 5 6 17 34 _
28 14 15 16 33 _ _
29 30 31 32 _ _ _
Run Code Online (Sandbox Code Playgroud)
使用Mathematica的简单方法是什么?
Leo*_*rin 12
有了这个辅助函数:
Clear[makeSteps];
makeSteps[0] = {};
makeSteps[m_Integer?Positive] :=
Most@Flatten[
Table[#, {m}] & /@ {{-1, 0}, {-1, 1}, {0, 1}, {1, 0}, {1, -1}, {0, -1}}, 1];
Run Code Online (Sandbox Code Playgroud)
我们可以将矩阵构造为
constructMatrix[n_Integer?OddQ] :=
Module[{cycles, positions},
cycles = (n+1)/2;
positions =
Flatten[FoldList[Plus, cycles + {#, -#}, makeSteps[#]] & /@
Range[0, cycles - 1], 1];
SparseArray[Reverse[positions, {2}] -> Range[Length[positions]]]];
Run Code Online (Sandbox Code Playgroud)
要获得您描述的矩阵,请使用
constructMatrix[7] // MatrixForm
Run Code Online (Sandbox Code Playgroud)
这背后的想法是检查连续数字1的位置遵循的模式.你可以看到这些形成了循环.第0个循环是微不足道的 - 在位置包含1号{0,0}
(如果我们从中心计算位置).下一个循环是通过将第一个数字(2)置于位置{1,-1}
并逐步增加以下步骤形成的{0, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 0}
(当我们围绕中心移动时).第二个周期是类似的,但我们必须从头开始{2,-2}
,重复前面的每个步骤两次,并添加第六步(向上),重复一次:{0, -1}
.第三个循环是类似的:从开始{3,-3}
,重复所有步骤3次,除了{0,-1}
重复仅两次.辅助功能makeSteps
使过程自动化.在主要功能中,我们必须一起收集所有位置,然后添加到它们,{cycles, cycles}
因为它们是从具有位置的中心计算的{cycles,cycles}
.最后,我们构建SparseArray
了这些位置.
我不知道Mathematica语法,但我想你可以使用这样的算法:
start in the middle of the matrix
enter a 1 into the middle
go up-right (y-1 / x+1)
set integer iter=1
set integer num=2
while cursor is in matrix repeat:
enter num in current field
increase num by 1
repeat iter times:
go left (x-1 / y)
enter num in current field
increase num by 1
repeat iter times:
go down-left (x-1 / y+1)
enter num in current field
increase num by 1
repeat iter times:
go down (x / y+1)
enter num in current field
increase num by 1
repeat iter times:
go right (x+1 / y)
enter num in current field
increase num by 1
repeat iter times:
go up-right (x+1 / y-1)
enter num in current field
increase num by 1
repeat iter-1 times:
go up (x / y-1)
enter num in current field
increase num by 1
go up-up-right (y-2 / x+1)
increase iter by 1
Run Code Online (Sandbox Code Playgroud)
您也可以很容易地将此算法转换为功能版本或尾递归.
好吧,如果你没有出界,你必须检查while循环.如果n是奇数,那么你可以只计算num up:
m = floor(n/2)
num <= n*n - (m+m*m)
Run Code Online (Sandbox Code Playgroud)
我很确定有一个更简单的算法,但对我来说这是最直观的算法.
归档时间: |
|
查看次数: |
556 次 |
最近记录: |