【问题标题】:sample from a vector to get a particular pattern从向量中采样以获得特定模式
【发布时间】:2020-09-26 23:50:14
【问题描述】:

我有一个向量a= c (1, 2, 3)

我可以得到一个程序来安排向量来得到任何一个

b=c (3, 1, 2)b=c (2, 3, 1)

使用 sample (a,3,replace=FALSE) 会给我 (1,2,3),(1,3,2) 等,有时这是我不想要的结果拥有。

【问题讨论】:

    标签: r vector sample


    【解决方案1】:

    如果您想要混乱(没有固定点的排列),那么您可以查找:

    Efficiently create derangement of a vector in R

    然后阅读:

    https://www.cs.upc.edu/~conrado/research/talks/analco08.pdf

    这是基于链接的我的代码:

    nDerangment <- function(n){
      
      if(n <= 1) return(0)
      if(n == 2) return(1)
      (n - 1) * (nDerangment(n - 1) + nDerangment(n - 2))
    }
    
    randomDerangement <- function(n){
      
      if(n == 1) return (n)
      
      p <- seq_len(n)
      mark <- rep(FALSE, n)
      
      i <- u <- n
      while(u >= 2){
        
        if(!mark[i]){
          
          repeat{
            j <- sample(i-1, 1)
            if(!mark[j]) 
              break()
          }
        
          temp <- p[i]
          p[i] <- p[j]
          p[j] <- temp
        
          prob <- runif(n = 1, 0 , 1)
          if(prob < (u-1) * nDerangment(u-2) / nDerangment(u)){
            mark[j] <- TRUE
            u <- u - 1
          }
          
          u <- u - 1
        }
        
        i <- i-1
      }
      
      p
    }
    

    因为我递归地计算混乱的数量,这仅适用于生成合理小的n 的混乱。当然,与斐波那契数类似,用于计算紊乱的更好的函数是:

    nDerangment <- function(n){
      
      if(n <= 1) return(0)
      if(n == 2) return(1)
      
      d_minus_two <- 0
      d_minus_one <- 1
      
      i <- 3
      while(i <= n){
        
        next_d <- (i - 1) * d_minus_one + d_minus_two
        d_minus_two <- d_minus_one
        d_minus_one <- next_d
        
        i <- i + 1
      }
      
      next_d
    }
    

    请注意,您还可以通过在全局序列中存储错位数来更有效地在if 语句中编写计算数字的函数:

    max_d <- 30
    derangements <- vector("integer", max_d)
    derangements[[1]] <- 0
    derangements[[2]] <- 1
    cur_index <- 2
    
    my_fun <- function(n){
      
      if(n > max_d){
        new_vector <- vector("integer", 2*max_d)
        new_vector[seq_len(max_d)] <- derangements
        derangements <<- new_vector
        max_d <<- 2*max_d
      }
      
      if(n <= cur_index) return(derangements[[n]])
      
      for(i in (cur_index+1):n)
        derangements[[i]] <<- i * derangements[[i-1]] + derangements[[i-2]]
      
      
      derangements[[n]]
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-19
      • 1970-01-01
      • 1970-01-01
      • 2014-06-02
      • 2017-12-07
      相关资源
      最近更新 更多