我有一份人员名单:
people<-c("Betty", "Joe", "Bob", "Will", "Frank")
我想为每个人随机分配两个人(不允许自行分配),并且我希望每个人被分配给另一个人的次数相等(在上面的示例中,每个人只能被分配给另一个人两次) .
因此,例如比赛可能是
贝蒂(乔和鲍勃)、乔(鲍勃和威尔)、鲍勃(威尔和弗兰克)、威尔(弗兰克和贝蒂)
当然,我刚刚使用了他们的排序,但如果这可以随机化就好了。
任何想法从哪里开始?
我有一份人员名单:
people<-c("Betty", "Joe", "Bob", "Will", "Frank")
我想为每个人随机分配两个人(不允许自行分配),并且我希望每个人被分配给另一个人的次数相等(在上面的示例中,每个人只能被分配给另一个人两次) .
因此,例如比赛可能是
贝蒂(乔和鲍勃)、乔(鲍勃和威尔)、鲍勃(威尔和弗兰克)、威尔(弗兰克和贝蒂)
当然,我刚刚使用了他们的排序,但如果这可以随机化就好了。
任何想法从哪里开始?
新的(更简单的)解决方案:使用来自 Ari B. Friedman 的包中的shift
函数TaRifx
tt <- sample(people)
lapply(seq_len(length(tt))-1, function(x) shift(tt, x)[1:3])
# if you don't want it to be ordered, just add a sample(.)
lapply(seq_len(length(tt))-1, function(x) sample(shift(tt, x)[1:3]))
# [[1]]
# [1] "Bob" "Frank" "Betty"
#
# [[2]]
# [1] "Frank" "Betty" "Joe"
#
# [[3]]
# [1] "Betty" "Joe" "Will"
#
# [[4]]
# [1] "Joe" "Will" "Bob"
#
# [[5]]
# [1] "Will" "Bob" "Frank"
旧解决方案(对于这个想法):
我会走这条路。基本上,一旦你sample
“人”,你总是可以去,1、2、3、2、3、4、3、4、5、4、5、1。所以,让我们这样做。也就是说,生成这些索引,然后对人员进行抽样并获得三元组。
# generate index
len <- length(people)
choose <- 3 # at a time
idx <- outer(seq(choose), seq(choose+2)-1, '+')
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 2 3 4 5
# [2,] 2 3 4 5 6
# [3,] 3 4 5 6 7
# sample people
tt <- sample(people)
# [1] "Joe" "Will" "Bob" "Frank" "Betty"
max.idx <- 2*choose + 1
tt[(len+1):max.idx] <- tt[seq(max.idx-len)]
# [1] "Joe" "Will" "Bob" "Frank" "Betty" "Joe" "Will"
tt[idx]
# [1] "Joe" "Will" "Bob" "Will" "Bob" "Frank" "Bob" "Frank" "Betty" "Frank"
# [15] "Betty" "Joe" "Betty" "Joe" "Will"
split(tt[idx], gl(ncol(idx), nrow(idx)))
# $`1`
# [1] "Joe" "Will" "Bob"
#
# $`2`
# [1] "Will" "Bob" "Frank"
#
# $`3`
# [1] "Bob" "Frank" "Betty"
#
# $`4`
# [1] "Frank" "Betty" "Joe"
#
# $`5`
# [1] "Betty" "Joe" "Will"
现在我们可以把这一切放在一个函数中:
my_sampler <- function(x, choose) {
len <- length(x)
idx <- outer(seq(choose), seq(choose+2)-1, '+')
sx <- sample(x)
max.idx <- 2*choose + 1
sx[(len+1):max.idx] <- sx[seq(max.idx-len)]
split(sx[idx], gl(ncol(idx), nrow(idx)))
}
# try it out
my_sampler(people, 3)
my_sampler(people, 4) # 4 at a time
# if you want this and want a non-ordered solution, wrap this with `lapply` and `sample`
lapply(my_sampler(people, 3), sample)
有趣的问题。这会让你走到一半。缺少的一点是对人们处于相同数量的伙伴关系中的限制。如果您想将两个人随机分配给除他们自己以外的某个人,这可以像这样在一个班轮中实现......
assigns <- lapply( people , function(x) { c( x , sample( people[!(people %in% x)] , 2 ) ) } )
第一个人将被分配,最后两个将被分配。
assigns
#[[1]]
#[1] "Betty" "Bob" "Will"
#[[2]]
#[1] "Joe" "Bob" "Frank"
#[[3]]
#[1] "Bob" "Betty" "Joe"
#[[4]]
#[1] "Will" "Betty" "Joe"
#[[5]]
#[1] "Frank" "Will" "Betty"