【发布时间】: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) 等,有时这是我不想要的结果拥有。
【问题讨论】:
我有一个向量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) 等,有时这是我不想要的结果拥有。
【问题讨论】:
如果您想要混乱(没有固定点的排列),那么您可以查找:
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]]
}
【讨论】: