简体   繁体   English

如何在R中构造一个螺旋矩阵?

[英]How to construct a spiral matrix in R?

I was trying to create a spiral matrix like below (given dimension N , where N=4 in the following figure)我试图创建一个如下所示的螺旋矩阵(给定维度N ,其中N=4在下图中)

在此处输入图像描述

Is there any R package that has implemented it?有没有实现它的R package? I did not find it.我没有找到它。 Otherwise, can anyone help me to built it within base R operations?否则,谁能帮我在基本的 R 操作中构建它? Thanks in advance!提前致谢!

I am not sure if there is a package particularly including the spiral matrix construction, so I just provide a base R solution我不确定是否有 package 特别包括螺旋矩阵结构,所以我只提供一个基本的 R 解决方案

SpiralMatrix <- function(n) {
  M <- matrix(nrow = n,ncol = n);
  #  start from element M(1,1)
  i <- j <- 1;
  s <- 1; # first element assigned to M(1,1)
  M[i,j] = s;
  repeat {
    #  fill row from left to right
    idx <- tail(which(is.na(M[i,])),1);
    M[i,j:idx] <- s + (0:(idx-j));
    s <- s + idx - j;
    j <- idx;
    if (all(!is.na(M))) break

    #  fill column from top to bottom
    idx <- tail(which(is.na(M[,j])),1);
    M[i:idx,j] <- s + (0:(idx-i));
    s <- s + idx - i;
    i <- idx;
    if (all(!is.na(M))) break

    #  fill row from right to left
    idx <- head(which(is.na(M[i,])),1);
    M[i,j:idx] <- s + (0:(j-idx));
    s <- s + j - idx;
    j <- idx;
    if (all(!is.na(M))) break

    # fill column from bottom to top
    idx <- head(which(is.na(M[,j])),1);
    M[i:idx,j] <- s + (0:(i-idx));
    s <- s + i-idx;
    i <- idx;
    if (all(!is.na(M))) break
  }
  M
}

such that这样

> SpiralMatrix(5)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    4    5
[2,]   16   17   18   19    6
[3,]   15   24   25   20    7
[4,]   14   23   22   21    8
[5,]   13   12   11   10    9
> SpiralMatrix(4)
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]   12   13   14    5
[3,]   11   16   15    6
[4,]   10    9    8    7

So i had a need for Spiral Matrix starting from middle.所以我需要从中间开始的螺旋矩阵。 Solution below.下面的解决方案。

# Spiral matrix Generation

# Func Generating starting matrix, integer cellRange must be UNEVEN
StartMatrix = function(cellRange){
  if((cellRange %% 2) == 0){
    print("cellRange must be UNEVEN integer.")
  }
  else{
    return(matrix(1,cellRange,cellRange))      
  }

}

Matrix = StartMatrix(11)
# Starts in middle
Column_Position = round(ncol(Matrix)/2)
Row_Position = round(nrow(Matrix)/2)
# Starting parameters
Number = 1
Direction = factor('Right', levels = c('Right', 'Up','Left','Down'))
step = 0
Side_counter = 0
stepLeft = 1
# Sequence
for (i in c(1:(nrow(Matrix)*ncol(Matrix)))){
  Matrix[Row_Position,Column_Position] = Number
  # Position changer
  if(Direction == 'Right'){
    Column_Position<<-Column_Position+1
    Row_Position<<-Row_Position
  }
  if(Direction == 'Up'){
    Column_Position<<-Column_Position
    Row_Position<<-Row_Position-1
  }
  if(Direction == 'Left'){
    Column_Position<<-Column_Position-1
    Row_Position<<-Row_Position
  }
  if(Direction == 'Down'){
    Column_Position <<- Column_Position
    Row_Position <<- Row_Position+1
  }
  # If number of steps reaches side end. Direction is changed. Steps resets to 0 
  step = step + 1
  if (step == stepLeft){
    Side_counter <<- Side_counter + 1
    step = 0
    if(Direction == 'Right'){
      Direction = "Up"
    }else if(Direction == 'Up'){
      Direction = "Left"
    }else if(Direction == 'Left'){
      Direction = "Down"
    }else if(Direction == 'Down'){
      Direction = "Right"
    }
  }
  # Each second time direction is changed Steps that can be done rises by 1.
  if (Side_counter == 2){
    Side_counter<<-0 
    stepLeft<<-stepLeft +1
  }
  Number <<- Number + 1
}
  
Matrix

result:结果:

    > Matrix
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
 [1,]  101  100   99   98   97   96   95   94   93    92    91
 [2,]  102   65   64   63   62   61   60   59   58    57    90
 [3,]  103   66   37   36   35   34   33   32   31    56    89
 [4,]  104   67   38   17   16   15   14   13   30    55    88
 [5,]  105   68   39   18    5    4    3   12   29    54    87
 [6,]  106   69   40   19    6    1    2   11   28    53    86
 [7,]  107   70   41   20    7    8    9   10   27    52    85
 [8,]  108   71   42   21   22   23   24   25   26    51    84
 [9,]  109   72   43   44   45   46   47   48   49    50    83
[10,]  110   73   74   75   76   77   78   79   80    81    82
[11,]  111  112  113  114  115  116  117  118  119   120   121

Similar result can be also obtained by doing some simple transformations to solution provided by Thomas.通过对 Thomas 提供的解决方案进行一些简单的转换,也可以获得类似的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM