1 module ProposalMatch where
3 import Data.Array.IArray
4 import Data.Graph.Inductive.Graph
5 import Data.Graph.Inductive.Tree
8 import ProposalMatchConfig
10 data Instance = Instance
13 (Int -> Wt) -- reviewer -> relative load
14 (Int -> Int -> Wt) -- reviewer -> proposal -> pref
16 prefBoringness p = if prefIsVeryBoring p then 2
17 else if prefIsBoring p then 1 else 0
18 prefExpertness p = if prefIsExpert p then 2
19 else if prefIsKnowledgeable p then 1 else 0
21 doReduction :: Instance -> Gr () Wt
22 doReduction (Instance numRvrs numProps rloadF prefF) =
26 rvrNode i boringness = 2 + 3*i + boringness
27 propNode j expertness = 2 + 3*numRvrs + 3*j + expertness
28 numNodes = 2 + 3*numRvrs + 3*numProps
31 totalReviews = reviewsEachProposal * numProps
32 totalRelativeLoad = foldl (+) 0 (map rloadF [0 .. numRvrs - 1])
33 targetLoad i = ceiling (numAsWt totalReviews * rloadF i / totalRelativeLoad)
34 -- A...H refer to idea book p.429
36 i <- [0 .. numRvrs - 1]
38 l <- [0 .. tl + loadTolerance - 1]
41 else marginalLoadCost ((numAsWt (l - tl) + 1/2) / numAsWt loadTolerance)
42 let edgeA = (source, rvrNode i 0, costA)
43 let costB = marginalBoringCost ((numAsWt l + 1/2) / numAsWt tl)
44 let edgeB = (rvrNode i 0, rvrNode i 1, costB)
45 let costC = marginalVeryBoringCost ((numAsWt l + 1/2) / numAsWt tl)
46 let edgeC = (rvrNode i 1, rvrNode i 2, costC)
49 i <- [0 .. numRvrs - 1]
50 j <- [0 .. numProps - 1]
52 if prefIsConflict pref
54 else [(rvrNode i (prefBoringness pref),
55 propNode j (prefExpertness pref),
58 j <- [0 .. numProps - 1]
59 [(propNode j 2, propNode j 0, -expertBonus)]
61 j <- [0 .. numProps - 1]
62 l <- [0 .. reviewsEachProposal - 1]
63 let edgeF = (propNode j 2, propNode j 1, 0)
64 let edgeG = (propNode j 1, propNode j 0,
65 if l == 0 then -knowledgeableBonus else 0)
66 let edgeH = (propNode j 0, sink, 0)
68 theNodes = [(x, ()) | x <- [0 .. numNodes - 1]]
69 theEdges = edgesABC ++ edgesD ++ edgesE ++ edgesFGH
71 mkGraph theNodes theEdges
74 -- Returns a list of reviews as ordered pairs (reviewer#, proposal#).
75 doMatching :: Instance -> [(Int, Int)]
76 doMatching inst@(Instance numRvrs numProps rloadF prefF) =
77 -- Copied from doReduction. There should be a better way to get these here.
81 rvrNode i boringness = 2 + 3*i + boringness
82 propNode j expertness = 2 + 3*numRvrs + 3*j + expertness
83 firstPropNode = propNode 0 0
84 idPropNode n = (n - (2 + 3*numRvrs)) `div` 3
85 numNodes = 2 + 3*numRvrs + 3*numProps
87 let graph1 = doReduction inst in
88 let flow1 = flowDiff graph1 (snd (umcf source sink graph1)) in
90 i <- [0 .. numRvrs - 1]
91 boringness <- [0, 1, 2]
92 n <- suc flow1 (rvrNode i boringness)
94 then [(i, idPropNode n)]
97 sort pairs -- for prettiness