有N个组(也就是法官,比方说17个)和M个元素(让我们称之为案例,比方说22个)使得3 * M <= 4 * N.
N <- LETTERS[1:17]
M <- 1:22
我想为N个法官中的每一个分配4个或更少的案件,这样每个案件的评估不会多于或少于3个法官,并且没有法官两次看同一案件。
A : 1, 2, 19
B : 2, 3, 8, 22
...
Q : 1, 2, 12, 10
在R中进行任何快速简便的方法吗?
到目前为止试过这个:
df <- data.frame(ID=rep(M,3))
values <- N
df$values[sample(1:nrow(df), nrow(df), FALSE)] <- rep(values, 4)
答案 0 :(得分:5)
通常当我看到&#34;随机分配受到约束时#34;问题,我的想法是:
在R中使用像lpSolve这样的线性编程包非常简单,创建一个二进制变量x_ij,指示我们是否为每个案例/判断对分配案例i来判断j:
library(lpSolve)
set.seed(144)
# vars is a convenience matrix that tells us the i and j index of each variable in our model
vars <- expand.grid(i=M, j=N)
mod <- lp(direction = "max",
objective.in = rnorm(nrow(vars)),
const.mat = rbind(t(sapply(M, function(i) as.numeric(vars$i == i))),
t(sapply(N, function(j) as.numeric(vars$j == j)))),
const.dir = rep(c("=", "<="), c(length(M), length(N))),
const.rhs = rep(c(3, 4), c(length(M), length(N))),
all.bin = TRUE)
# Extract all cases assigned to each judge
sapply(N, function(j) vars$i[mod$solution > 0.999 & vars$j == j])
# $A
# [1] 2 10 15
#
# $B
# [1] 7 8 13 22
#
# $C
# [1] 2 3 7 9
# ...
顺便说一下,我们设置了权重和约束,这实际上可以被认为是从所有可行的案例分配到法官的随机选择。
答案 1 :(得分:4)
这就是我要做的事情:
set.seed(1)
rM = sample(M)
rN = sample(N)
tasks = rep(rM, each=3)
judges = rep(rN, length.out = length(tasks))
matches = data.frame(judges, tasks)
您可以通过制表来验证您的条件是否成立:
tab = with(matches, table(judges, tasks))
max(tab) # 1
addmargins(tab)
tasks
judges 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Sum
A 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 4
B 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 4
C 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 4
D 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 1 0 0 4
E 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 4
F 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 4
G 0 0 1 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 4
H 1 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 4
I 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 0 4
J 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1 0 0 4
K 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 4
L 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 4
M 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 3
N 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 3
O 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0 4
P 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 4
Q 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 4
Sum 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 66
注意:在rN
中靠近的评委将绘制类似的案例负载。
答案 2 :(得分:2)
GetJudgeCaseList <- function(CaseList, judgeList, casesAllowed, NumJudges) {
e <- new.env()
e$casesLeft <- data.frame(Judges = judgeList, itersLeft = casesAllowed)
e$judgeList = judgeList
doCase <- function(i) {
pickJudges <- function(NumJudges, judgeList) {
CurJudges <- sample(judgeList, NumJudges)
return(CurJudges)
}
case <- pickJudges(NumJudges, e$judgeList)
e$casesLeft[casesLeft$Judges%in%case, 2] <- e$casesLeft[casesLeft$Judges%in%case, 2] - 1
e$judgeList <- e$casesLeft$Judges[e$casesLeft$itersLeft!=0]
return(data.frame(Case = CaseList[i], judges = paste0(case, collapse = ", ")))
}
Cases <- do.call(rbind, lapply(1:length(CaseList), doCase))
return(Cases)
}
GetJudgeCaseList(CaseList = c(1:22), judgeList = N, casesAllowed = 4, NumJudges = 3)
Case judges
1 1 a, h, o
2 2 k, i, j
3 3 j, q, a
4 4 j, n, p
5 5 g, o, n
6 6 q, g, l
7 7 g, d, i
8 8 b, l, f
9 9 m, b, i
10 10 k, m, c
11 11 l, m, p
12 12 m, o, q
13 13 p, g, b
14 14 p, f, b
15 15 l, e, i
16 16 d, h, o
17 17 d, c, q
18 18 a, f, e
19 19 e, d, c
20 20 e, n, k
21 21 a, k, f
22 22 j, n, c