+++ /dev/null
-module ProposalMatch where
-import UnitMinCostFlow
-import Data.Array.IArray
-import Data.Graph.Inductive.Graph
-import Data.Graph.Inductive.Tree
-import Data.List
-
-import ProposalMatchConfig
-
-data Instance = Instance
- Int -- numReviewers
- Int -- numProposals
- (Int -> Wt) -- reviewer -> relative load
- (Int -> Int -> Wt) -- reviewer -> proposal -> pref
-
-prefBoringness p = if prefIsVeryBoring p then 2
- else if prefIsBoring p then 1 else 0
-prefExpertness p = if prefIsExpert p then 2
- else if prefIsKnowledgeable p then 1 else 0
-
-doReduction :: Instance -> Gr () Wt
-doReduction (Instance numRvrs numProps rloadF prefF) =
- let
- source = 0
- sink = 1
- rvrNode i boringness = 2 + 3*i + boringness
- propNode j expertness = 2 + 3*numRvrs + 3*j + expertness
- numNodes = 2 + 3*numRvrs + 3*numProps
- in
- let
- totalReviews = reviewsEachProposal * numProps
- totalRelativeLoad = foldl (+) 0 (map rloadF [0 .. numRvrs - 1])
- targetLoad i = ceiling (numAsWt totalReviews * rloadF i / totalRelativeLoad)
- -- A...H refer to idea book p.429
- edgesABC = do
- i <- [0 .. numRvrs - 1]
- let tl = targetLoad i
- l <- [0 .. tl + loadTolerance - 1]
- let costA = if l < tl
- then 0
- else marginalLoadCost ((numAsWt (l - tl) + 1/2) / numAsWt loadTolerance)
- let edgeA = (source, rvrNode i 0, costA)
- let costB = marginalBoringCost ((numAsWt l + 1/2) / numAsWt tl)
- let edgeB = (rvrNode i 0, rvrNode i 1, costB)
- let costC = marginalVeryBoringCost ((numAsWt l + 1/2) / numAsWt tl)
- let edgeC = (rvrNode i 1, rvrNode i 2, costC)
- [edgeA, edgeB, edgeC]
- edgesD = do
- i <- [0 .. numRvrs - 1]
- j <- [0 .. numProps - 1]
- let pref = prefF i j
- if prefIsConflict pref
- then []
- else [(rvrNode i (prefBoringness pref),
- propNode j (prefExpertness pref),
- assignmentCost pref)]
- edgesE = do
- j <- [0 .. numProps - 1]
- [(propNode j 2, propNode j 0, -expertBonus)]
- edgesFGH = do
- j <- [0 .. numProps - 1]
- l <- [0 .. reviewsEachProposal - 1]
- let edgeF = (propNode j 2, propNode j 1, 0)
- let edgeG = (propNode j 1, propNode j 0,
- if l == 0 then -knowledgeableBonus else 0)
- let edgeH = (propNode j 0, sink, 0)
- [edgeF, edgeG, edgeH]
- theNodes = [(x, ()) | x <- [0 .. numNodes - 1]]
- theEdges = edgesABC ++ edgesD ++ edgesE ++ edgesFGH
- in
- mkGraph theNodes theEdges
-
-todo = undefined
--- Returns a list of reviews as ordered pairs (reviewer#, proposal#).
-doMatching :: Instance -> [(Int, Int)]
-doMatching inst@(Instance numRvrs numProps rloadF prefF) =
- -- Copied from doReduction. There should be a better way to get these here.
- let
- source = 0
- sink = 1
- rvrNode i boringness = 2 + 3*i + boringness
- propNode j expertness = 2 + 3*numRvrs + 3*j + expertness
- firstPropNode = propNode 0 0
- idPropNode n = (n - (2 + 3*numRvrs)) `div` 3
- numNodes = 2 + 3*numRvrs + 3*numProps
- in
- let graph1 = doReduction inst in
- let flow1 = flowDiff graph1 (snd (umcf source sink graph1)) in
- let pairs = do
- i <- [0 .. numRvrs - 1]
- boringness <- [0, 1, 2]
- n <- suc flow1 (rvrNode i boringness)
- if n >= firstPropNode
- then [(i, idPropNode n)]
- else []
- in
- sort pairs -- for prettiness