Commit | Line | Data |
---|---|---|
05a6f0ed MM |
1 | module PMInstanceGenerator where |
2 | import PMInstance | |
8723ed6a | 3 | import PMConfig |
967c39ef MM |
4 | import System.Random |
5 | import RandomizedMonad | |
6 | import Data.Array.IArray | |
7 | import ArrayStuff | |
8 | ||
967c39ef | 9 | -- Expertise on each of the topics |
066d7f53 MM |
10 | data ReviewerInfo = ReviewerInfo { |
11 | riTopicExpertness :: Array Int Double, | |
12 | riConflicts :: [Int] | |
13 | } | |
967c39ef | 14 | |
8723ed6a | 15 | randomReviewerInfo cfg numProps = do |
89b7fd0d MM |
16 | -- "Older" reviewers are more likely to be expert on topics. |
17 | age <- mrandomR (0.5, 1.0) | |
8723ed6a | 18 | expns <- indRandomArray (0, numTopics cfg - 1) $ |
89b7fd0d | 19 | withProb [(0.15 * age, return 2), (0.4 * age, return 1)] (return 0) |
066d7f53 MM |
20 | -- Samir: "Its often the case that each reviewer has a COI with say |
21 | -- one proposal submitted either by their University (different faculty) | |
22 | -- or by a recent co-author." | |
23 | conflicts <- withProb [(0.7, do | |
24 | cp <- mrandomR (0, numProps-1) | |
25 | return [cp] | |
26 | )] (return []) | |
27 | return (ReviewerInfo expns conflicts) | |
967c39ef MM |
28 | |
29 | -- One topic or two different topics | |
30 | data ProposalTopics = PTopic1 Int | PTopic2 Int Int | |
31 | ||
066d7f53 MM |
32 | data ProposalInfo = ProposalInfo { |
33 | piTopics :: ProposalTopics, | |
34 | piDifficulty :: Wt | |
35 | } | |
967c39ef | 36 | |
8723ed6a | 37 | randomTopic cfg = withWeight $ |
96fe6497 | 38 | map (\i -> (widenInteger (i+1) ** topicZipfExponent cfg, return i)) |
8723ed6a MM |
39 | [0 .. numTopics cfg - 1] |
40 | ||
41 | randomProposalInfo cfg = do | |
066d7f53 | 42 | topics <- do |
8723ed6a | 43 | t1 <- randomTopic cfg |
066d7f53 | 44 | withProb [(0.5, return $ PTopic1 t1)] (do |
8723ed6a | 45 | t2 <- filterRandomized (/= t1) $ randomTopic cfg |
066d7f53 MM |
46 | return $ PTopic2 t1 t2 |
47 | ) | |
967c39ef | 48 | diff <- mrandomR (3, 5) |
066d7f53 | 49 | return (ProposalInfo topics (fromInteger diff)) |
967c39ef MM |
50 | |
51 | expertnessToPref expertness = if expertness == 0 then 7 | |
52 | else if expertness == 1 then 5 | |
53 | else 3 | |
54 | ||
8723ed6a MM |
55 | randomInstance :: PMConfig -> Int -> Int -> Randomized PMInstance |
56 | randomInstance cfg numRvrs numProps = do | |
57 | reviewerInfos <- indRandomArray (0, numRvrs-1) $ randomReviewerInfo cfg numProps | |
066d7f53 | 58 | :: Randomized (Array Int ReviewerInfo) |
8723ed6a | 59 | proposalInfos <- indRandomArray (0, numProps-1) $ randomProposalInfo cfg |
066d7f53 MM |
60 | :: Randomized (Array Int ProposalInfo) |
61 | let loadA = constArray (0, numRvrs-1) 1 | |
967c39ef MM |
62 | let prefA = funcArray ((0, 0), (numRvrs-1, numProps-1)) (\(i,j) -> |
63 | let | |
066d7f53 MM |
64 | ReviewerInfo iTE iC = reviewerInfos ! i |
65 | ProposalInfo jT jD = proposalInfos ! j | |
66 | isConflict = elem j iC | |
67 | topicPref = case jT of | |
68 | PTopic1 jt1 -> expertnessToPref (iTE ! jt1) | |
69 | PTopic2 jt1 jt2 -> (expertnessToPref (iTE ! jt1) | |
70 | + expertnessToPref (iTE ! jt2)) / 2 | |
71 | in if isConflict then 40 else topicPref * jD - 4) | |
05a6f0ed | 72 | return $ PMInstance numRvrs numProps loadA prefA |