Make the instance generator select proposal topics from a Zipf distribution, and
[match/match.git] / program / PMInstanceGenerator.hs
index 97a546a..0f78b02 100644 (file)
@@ -1,22 +1,21 @@
 module PMInstanceGenerator where
 import PMInstance
+import PMConfig
 import System.Random
 import RandomizedMonad
 import Data.Array.IArray
 import ArrayStuff
 
-numTopics = 20
-
 -- Expertise on each of the topics
 data ReviewerInfo = ReviewerInfo {
        riTopicExpertness :: Array Int Double,
        riConflicts       :: [Int]
 }
 
-randomReviewerInfo numProps = do
+randomReviewerInfo cfg numProps = do
        -- "Older" reviewers are more likely to be expert on topics.
        age <- mrandomR (0.5, 1.0)
-       expns <- indRandomArray (0, numTopics-1) $
+       expns <- indRandomArray (0, numTopics cfg - 1) $
                withProb [(0.15 * age, return 2), (0.4 * age, return 1)] (return 0)
        -- Samir: "Its often the case that each reviewer has a COI with say
        -- one proposal submitted either by their University (different faculty)
@@ -35,11 +34,15 @@ data ProposalInfo = ProposalInfo {
        piDifficulty :: Wt
 }
 
-randomProposalInfo = do
+randomTopic cfg = withWeight $
+       map (\i -> (numAsWt (i+1) ** topicZipfExponent cfg, return i))
+               [0 .. numTopics cfg - 1]
+
+randomProposalInfo cfg = do
        topics <- do
-               t1 <- mrandomR (0, numTopics-1)
+               t1 <- randomTopic cfg
                withProb [(0.5, return $ PTopic1 t1)] (do
-                       t2 <- filterRandomized (/= t1) $ mrandomR (0, numTopics-1)
+                       t2 <- filterRandomized (/= t1) $ randomTopic cfg
                        return $ PTopic2 t1 t2
                        )
        diff <- mrandomR (3, 5)
@@ -49,11 +52,11 @@ expertnessToPref expertness = if expertness == 0 then 7
        else if expertness == 1 then 5
        else 3
 
-randomInstance :: Int -> Int -> Randomized PMInstance
-randomInstance numRvrs numProps = do
-       reviewerInfos <- indRandomArray (0, numRvrs-1) $ randomReviewerInfo numProps
+randomInstance :: PMConfig -> Int -> Int -> Randomized PMInstance
+randomInstance cfg numRvrs numProps = do
+       reviewerInfos <- indRandomArray (0, numRvrs-1) $ randomReviewerInfo cfg numProps
                :: Randomized (Array Int ReviewerInfo)
-       proposalInfos <- indRandomArray (0, numProps-1) $ randomProposalInfo
+       proposalInfos <- indRandomArray (0, numProps-1) $ randomProposalInfo cfg
                :: Randomized (Array Int ProposalInfo)
        let loadA = constArray (0, numRvrs-1) 1
        let prefA = funcArray ((0, 0), (numRvrs-1, numProps-1)) (\(i,j) ->