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 Real wt => Instance wt = Instance Int Int (Int -> Int -> wt)
12 doReduction :: Real wt => Instance wt -> (Int -> Int) -> Gr () wt
13 doReduction (Instance numRvrs numProps prefF) expertCapF =
18 propNode j isExpert = 2 + numRvrs + 2*j + (if isExpert then 1 else 0)
19 numNodes = 2 + numRvrs + 2*numProps
20 theNodes = [(x, ()) | x <- [0 .. numNodes - 1]]
24 i <- [0 .. numRvrs - 1]
25 l <- [1 .. maxReviewerLoad]
26 return (source, rvrNode i, marginalLoadCost l)
28 i <- [0 .. numRvrs - 1]
29 j <- [0 .. numProps - 1]
31 if prefIsConflict pref
32 then fail "Conflict of interest"
33 else return (rvrNode i, propNode j (prefIsExpert pref),
36 j <- [0 .. numProps - 1]
37 let wExpert = expertCapF j
38 -- Yuck, too many kinds of integers.
39 let wGeneral = fromInteger wantGeneralReviews +
40 fromInteger wantReviewsSubstForExpert *
41 (fromInteger wantExpertReviews - wExpert)
42 let expertEdges = replicate wExpert (propNode j True, sink, 0)
43 let rolloverEdges = replicate wGeneral (propNode j True, propNode j False, 0)
44 let generalEdges = replicate wGeneral (propNode j False, sink, 0)
45 expertEdges ++ rolloverEdges ++ generalEdges
46 theEdges = loadEdges ++ prefEdges ++ wantEdges
48 mkGraph theNodes theEdges
51 -- Returns a list of reviews as ordered pairs (reviewer#, proposal#).
52 doMatching :: Real wt => Instance wt -> [(Int, Int)]
53 doMatching inst@(Instance numRvrs numProps prefF) =
54 -- Copied from doReduction. There should be a better way to get these here.
59 propNode j isExpert = 2 + numRvrs + 2*j + (if isExpert then 1 else 0)
60 idPropNode n = (n - (2 + numRvrs)) `div` 2
61 numNodes = 2 + numRvrs + 2*numProps
63 let graph1 = doReduction inst (const (fromInteger wantExpertReviews)) in
64 let flow1 = flowDiff graph1 (snd (umcf source sink graph1)) in
65 let expertCapF j = outdeg flow1 (propNode j True) in
66 let graph2 = doReduction inst expertCapF in
67 let flow2 = flowDiff graph2 (snd (umcf source sink graph2)) in
69 i <- [0 .. numRvrs - 1]
70 map (\n -> (i, idPropNode n)) (suc flow2 (rvrNode i)) in
71 sort pairs -- for prettiness