Fixed values not repeated over column and row

前端 未结 2 1300
夕颜
夕颜 2021-01-24 07:07

I want to create a matrix in R with a set number of variables (e.g. 1 to 10). Those variables should be randomly assigned over rows and columns BUT should not be repeated in eit

2条回答
  •  春和景丽
    2021-01-24 07:19

    This seems almost like generating a Sudoku grid. The code below works pretty fast, but some minor R optimizations could be done:

    backtrack = function(n = 10){
      x = matrix(NA, ncol = n, nrow = n)
      cells = list()
      k = 1
      for (i in 1:n){
        for (j in 1:n){
          cells[[k]] = sample(1:n)
          k = k + 1
        }
      }
    
      i = 0
      while (i < n*n){
        candidates = cells[[i + 1]]
        idx = sample(1:length(candidates), 1)
        val = candidates[idx]
    
        if (length(candidates) == 0){
          cells[[i + 1]] = sample(1:n)
          i = i - 1
          x[as.integer(i/n) + 1,  i %% n + 1] = NA
        }
        else {
          rr = as.integer(i/n) + 1
          cc = i %% n + 1
          if ((val %in% x[rr, ]) || (val %in% x[, cc])){
            candidates = candidates[-idx]
            cells[[i + 1]] = candidates
          }
          else{
            x[as.integer(i/n) + 1, i %% n + 1] = val
            candidates = candidates[-idx]
            cells[[i + 1]] = candidates
            i = i + 1
          }
        }
      }
      x
    }
    

    Testing:

    set.seed(1) # Please change this
    x = backtrack(10)
    print(x)
    
          [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
     [1,]    8   10    4    6    9    7    1    2    3     5
     [2,]    5    6    9    8    1   10    4    3    2     7
     [3,]   10    7    1    2    8    9    5    4    6     3
     [4,]    3    9    8   10    6    5    7    1    4     2
     [5,]    9    1    6    4    7    3    2    5   10     8
     [6,]    1    4   10    3    2    6    8    7    5     9
     [7,]    2    8    5    9   10    1    3    6    7     4
     [8,]    6    5    2    7    3    4   10    9    8     1
     [9,]    4    3    7    1    5    2    6    8    9    10
    [10,]    7    2    3    5    4    8    9   10    1     6
    
    
    any(apply(x, 1, function(r)any(duplicated(r)))) # FALSE
    any(apply(x, 2, function(r)any(duplicated(r)))) # FALSE
    

提交回复
热议问题