2016-03-04 40 views
3

有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) 

回答

5

通常當我看到「隨機分配受限制」的問題,我的思緒以下想法:

  1. 選擇指定的項目我到類別J A隨機重量(在這種情況下分配案例i判斷j)
  2. 使用線性規劃來確定滿足所有約束的分配(< =每個案例4個案例/判斷和3個評論)並賦予最大權重。

這與線性規劃軟件包等lpSolveř非常簡單,從而形成二元變量x_ij指示是否我們分配情況下,我判斷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 
# ... 

通過我們設置權重和約束的方式,這實際上可以被認爲是從法官的所有可行的案件分配中隨機選擇。

+0

是的,我目前手足無措,很高興看到我正朝着正確的方向 –

+0

感謝您的回答。我用它作爲這個例子的基礎:https://acoppock.github.io/subpages/Random_Assignment_Subject_To_Constraints.html –

+0

@AlexCoppock偉大的工作!這提醒了我的博士生導師Dimitris Bertsimas的一些工作,您可能會感興趣:http://www.mit.edu/~dbertsim/papers/Optimization/The%20Power%20of%20Optimization%20Over%20Randomization%20in% 20Designing%20Experiments%20Involving%20Small%20Samples.pdf。 – josliber

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 wil l繪製類似的案例加載。

+0

他可以改寫'judge = c(replicate(4,sample(N)))'。只是連接。 –

+0

感謝編輯@Serban。 Fyi,「hold」和「hold true」都適合。 – Frank

+0

@ A.Webb是的,我想過。由於我見過的一些糟糕的時機,我偏向於「矩陣」。 – Frank

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