填充此矩阵的简便方法?

时间:2011-11-21 08:50:28

标签: matrix wolfram-mathematica 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  _   _   _

使用 Mathematica 进行此操作的简单方法是什么?

5 个答案:

答案 0 :(得分: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];

我们可以将矩阵构造为

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]]]];

要获得您描述的矩阵,请使用

constructMatrix[7] // MatrixForm

这背后的想法是检查连续数字1的位置遵循的模式。你可以看到这些形成了循环。第零周期很简单 - 在位置{0,0}包含数字1(如果我们从中心计算位置)。下一个周期是通过在位置{1,-1}取第一个数字(2)并逐个添加以下步骤形成的:{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

答案 1 :(得分:8)

我不知道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

您也可以很容易地将此​​算法转换为功能版本或尾递归。

好吧,如果你没有出界,你必须检查while循环。如果n是奇数,则可以在以下情况下计数num:

m = floor(n/2)
num <= n*n - (m+m*m)

我很确定有一个更简单的算法,但对我来说这是最直观的算法。

答案 2 :(得分:4)

从1开始向上的对角线上的幻数可以从

到达
f[n_] := 2 Sum[2 m - 1, {m, 1, n}] + UnitStep[n - 3] Sum[2 m, {m, 1, n - 2}]

In  := f@Range@5
Out := {2, 8, 20, 38, 62}

有了这个,设置SparseArray应该很容易。我会玩一下它,看看有多难。

答案 3 :(得分:4)

第一版:

i = 10;
a = b = c = Array[0 &, {2 (2 i + 1), 2 (2 i + 1)}];
f[n_] := 3*n*(n + 1) + 1;
k = f[i - 2];
p[i_Integer] :=
  ToRules@Reduce[
    -x + y < i - 1 && -x + y > -i + 1 &&
     (2 i + 1 - x)^2 + (2 i + 1 - y)^2 <= 2 i i - 2 &&
     3 i - 1 > x > i + 1 &&
     3 i - 1 > y > i + 1, {x, y}, Integers];

((a[[Sequence @@ #]] = 1) & /@ ({x, y} /. {p[i]}));
((a[[Sequence @@ (# + {2, 2})]] = 0) & /@ ({x, y} /. {p[i - 1]}));

(b[[Sequence @@ #]] = k--)&/@((# + 2 i {1, 1}) &/@ (SortBy[(# - 2 i {1, 1}) &/@ 
       Position[a, 1], 
      N@(Mod[-10^-9 - Pi/4 + ArcTan[Sequence @@ #], 2  Pi]) &]));
c = Table[b[[2 (2 i + 1) - j, k]], {j, 2 (2 i + 1) - 1}, 
                                   {k, 2 (2 i + 1) - 1}];
MatrixPlot[c]

enter image description here

修改

更好的一个:

genMat[m_] := Module[{f, k, k1, i, n, a = {{1}}},
  f[n_] := 3*n*(n + 1) + 1;
  For[n = 1, n <= m, n++,
   a = ArrayPad[a, 1];
   k1 = (f[n - 1] + (k = f[n]) + 2)/2 - 1;
   For[i = 2, i <= n + 1, i++,  a[[i, 2n + 1]] = k--; a[[2-i+2 n, 1]] = k1--];
   For[i = n + 2, i <= 2 n + 1, i++, a[[i, 3n+2-i]] = k--; a[[-i,i-n]] = k1--];
   For[i = n, i >= 1, i--, a[[2n+1, i]] = k--;a[[1, -i + 2 n + 2]] = k1--];
   ];
  Return@MatrixForm[a];
  ]

genMat[5]

答案 4 :(得分:3)

部分解决方案,使用图像处理:

enter image description here

Image /@ (Differences@(ImageData /@ 
     NestList[
      Fold[ImageAdd, 
        p = #, (HitMissTransform[p, #, Padding -> 0] & /@
          {{{1}, {-1}},
           {{-1}, {-1}, {1}},
           {{1, -1, -1}},
           {{-1, -1, 1}},
           {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {1, 1, -1, -1}}, 
           {{-1, -1, -1,  1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}})] &, img, 4]))

enter image description here