代码之家  ›  专栏  ›  技术社区  ›  shampoo

构造无重复但部分输入固定的随机化矩阵

  •  4
  • shampoo  · 技术社区  · 7 年前

    我在构建一个随机矩阵时遇到了一个问题,在这个矩阵中,我已经有了部分值(需要保持固定,所以没有进一步的随机)。

    让我们看看:

     n <- 10 
    

    我确实希望我的第一行是我输入的数据。例如:

      row1<- c(1,4,7,6,5,3,2,8,9,10)
      row2<- c(10,7,3,2,1,4,5,9,8,6)
      row3<- c(9,2,4,3,8,7,10,1,6,5)
    

    为了绘制一个包含10行(和10列)的矩阵,我将这些行与样本相结合(不替换,因为我希望每行中的每个数字都是唯一的)。

     first.rows<-rbind(row1,row2,row3,sample(n,n,replace=F),sample(n,n,replace=F),sample(n,n,replace=F),sample(n,n,replace=F),sample(n,n,replace=F),sample(n,n,replace=F),sample(n,n,replace=F))
    

    输出:

         [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
    row1    1    4    7    6    5    3    2    8    9    10
    row2   10    7    3    2    1    4    5    9    8     6
    row3    9    2    4    3    8    7   10    1    6     5
            6    1    5    4    2   10    3    8    7     9
            2    5    7    8    9    6    1    3    4    10
           10    6    4    1    8    3    7    2    5     9
            8    5    3    2    4    1   10    7    6     9
           10    7    9    6    8    2    5    4    3     1
            1   10    8    4    7    3    5    2    6     9
            2    1   10    4    8    9    3    6    5     7
    

    到现在为止,一直都还不错。。 然而,现在我有一个问题,那就是没有控制列中的唯一数字。这就是我需要的。我之所以会这样,是因为我使用了rbind(因此只有无重复项的函数才适用于行)。但我不知道如何解决这个问题。第1-3行应该与现在完全相同。

    有什么想法吗?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Fernando    7 年前

    我认为我以前的解决方案 Fixed values not repeated over column and row 可以修改以工作。您需要一个解算器,但它不是从空网格开始,而是从预填充的矩阵开始:

    # x is your matrix, "not filled" values should be NA
    # x is a square matrix with dimension n (big n will take longer to converge)
    backtrack = function(x){
      n = ncol(x)
      stopifnot(ncol(x)==nrow(x))
    
      cells = list()
      k = 1
      for (i in 1:n){
        for (j in 1:n){
    
          if (is.na(x[i, j]))
            cells[[k]] = sample(1:n)
          else
            cells[[k]] = NULL
          k = k + 1
        }
      }
    
      i = 0
      while (i < n*n){
    
        if (is.null(cells[[i+1]])){
            i=i+1
            next
        }
    
        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
    }
    

    空初始矩阵

    set.seed(1)
    x = backtrack(matrix(NA, nrow = 10, ncol = 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
    

    m = matrix(NA, ncol = 10, nrow = 10)
    m[1, ] = c(1,4,7,6,5,3,2,8,9,10)
    m[2, ] = c(10,7,3,2,1,4,5,9,8,6)
    m[3, ] = c(9,2,4,3,8,7,10,1,6,5)
    
    x = backtrack(m)
    print(x)
         [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
     [1,]    1    4    7    6    5    3    2    8    9    10
     [2,]   10    7    3    2    1    4    5    9    8     6
     [3,]    9    2    4    3    8    7   10    1    6     5
     [4,]    5    9    6    8    3    2    4    7   10     1
     [5,]    7    1    5   10    9    6    3    2    4     8
     [6,]    2    5    8    1   10    9    6    3    7     4
     [7,]    6    3    1    4    7    5    8   10    2     9
     [8,]    8   10    9    5    4    1    7    6    3     2
     [9,]    3    6   10    9    2    8    1    4    5     7
    [10,]    4    8    2    7    6   10    9    5    1     3
    

    注意:我没有测试它的bug。