From 36f2f402c6e9e61d571691bb0585aa0ee7204e77 Mon Sep 17 00:00:00 2001 From: myuuuuun Date: Fri, 12 Jan 2018 15:46:17 +0900 Subject: [PATCH] add type Matching and update example notebook --- examples/examples.ipynb | 778 ++++++++++++++++++++++++++++++++++--- src/MatchingMarkets.jl | 2 + src/deferred_acceptance.jl | 26 +- src/types.jl | 105 +++++ 4 files changed, 827 insertions(+), 84 deletions(-) create mode 100644 src/types.jl diff --git a/examples/examples.ipynb b/examples/examples.ipynb index fdfe9ac..ccd4c1b 100644 --- a/examples/examples.ipynb +++ b/examples/examples.ipynb @@ -35,7 +35,9 @@ { "cell_type": "code", "execution_count": 2, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "m, n = 5, 4;" @@ -113,7 +115,11 @@ { "data": { "text/plain": [ - "([1, 2, 3, 4, 0], [1, 2, 3, 4])" + "MatchingMarkets.Matching(5, 4, \n", + " [1, 1] = true\n", + " [2, 2] = true\n", + " [3, 3] = true\n", + " [4, 4] = true)" ] }, "execution_count": 5, @@ -122,7 +128,7 @@ } ], "source": [ - "deferred_acceptance(m_prefs, f_prefs)" + "matching = deferred_acceptance(m_prefs, f_prefs)" ] }, { @@ -133,7 +139,7 @@ { "data": { "text/plain": [ - "([2, 3, 4, 1], [4, 1, 2, 3, 0])" + "false" ] }, "execution_count": 6, @@ -142,7 +148,226 @@ } ], "source": [ - "deferred_acceptance(f_prefs, m_prefs)" + "matching[1, 2]" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "true" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matching[2, 2]" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "4-element SparseVector{Bool,Int64} with 1 stored entry:\n", + " [2] = true" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matching[2, :]" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5-element SparseVector{Bool,Int64} with 1 stored entry:\n", + " [1] = true" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matching[:, 1]" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1-element Array{Int64,1}:\n", + " 1" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matching(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1-element Array{Int64,1}:\n", + " 2" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matching(2, inverse=true)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "MatchingMarkets.Matching(4, 5, \n", + " [4, 1] = true\n", + " [1, 2] = true\n", + " [2, 3] = true\n", + " [3, 4] = true)" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matching = deferred_acceptance(f_prefs, m_prefs)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1-element Array{Int64,1}:\n", + " 2" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matching(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1-element Array{Int64,1}:\n", + " 1" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matching(2, inverse=true)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Dict{Int64,Array{Int64,1}} with 4 entries:\n", + " 4 => [1]\n", + " 2 => [3]\n", + " 3 => [4]\n", + " 1 => [2]" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_all_pairs(matching)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Dict{Int64,Array{Int64,1}} with 5 entries:\n", + " 4 => [3]\n", + " 2 => [1]\n", + " 3 => [2]\n", + " 5 => Int64[]\n", + " 1 => [4]" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_all_pairs(matching, inverse=true)" ] }, { @@ -154,8 +379,10 @@ }, { "cell_type": "code", - "execution_count": 7, - "metadata": {}, + "execution_count": 17, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "m = n = 4;" @@ -163,7 +390,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -177,7 +404,7 @@ " 0 0 0 0" ] }, - "execution_count": 8, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -194,7 +421,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -208,7 +435,7 @@ " 0 0 0 0" ] }, - "execution_count": 9, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -225,36 +452,86 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "([1, 2, 3, 4], [1, 2, 3, 4])" + "MatchingMarkets.Matching(4, 4, \n", + " [1, 1] = true\n", + " [2, 2] = true\n", + " [3, 3] = true\n", + " [4, 4] = true)" ] }, - "execution_count": 10, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "deferred_acceptance(m_prefs, f_prefs)" + "matching = deferred_acceptance(m_prefs, f_prefs)" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "([4, 3, 2, 1], [4, 3, 2, 1])" + "1-element Array{Int64,1}:\n", + " 1" ] }, - "execution_count": 11, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matching(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1-element Array{Int64,1}:\n", + " 2" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matching(2, inverse=true)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "MatchingMarkets.Matching(4, 4, \n", + " [4, 1] = true\n", + " [3, 2] = true\n", + " [2, 3] = true\n", + " [1, 4] = true)" + ] + }, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -272,7 +549,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -285,7 +562,7 @@ " 2" ] }, - "execution_count": 12, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -297,36 +574,96 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "([1, 2, 1, 2, 3, 4, 3, 4], [1, 2, 2, 1, 3, 4, 4, 3], [1, 3, 5, 7, 9], [1, 3, 5, 7, 9])" + "MatchingMarkets.Matching(4, 4, \n", + " [1, 1] = true\n", + " [2, 1] = true\n", + " [1, 2] = true\n", + " [2, 2] = true\n", + " [3, 3] = true\n", + " [4, 3] = true\n", + " [3, 4] = true\n", + " [4, 4] = true)" ] }, - "execution_count": 13, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "deferred_acceptance(m_prefs, f_prefs, m_caps, f_caps)" + "matching = deferred_acceptance(m_prefs, f_prefs, m_caps, f_caps)" ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "([3, 4, 3, 4, 1, 2, 1, 2], [4, 3, 3, 4, 2, 1, 1, 2], [1, 3, 5, 7, 9], [1, 3, 5, 7, 9])" + "2-element Array{Int64,1}:\n", + " 1\n", + " 2" ] }, - "execution_count": 14, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matching(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2-element Array{Int64,1}:\n", + " 3\n", + " 4" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matching(3, inverse=true)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "MatchingMarkets.Matching(4, 4, \n", + " [3, 1] = true\n", + " [4, 1] = true\n", + " [3, 2] = true\n", + " [4, 2] = true\n", + " [1, 3] = true\n", + " [2, 3] = true\n", + " [1, 4] = true\n", + " [2, 4] = true)" + ] + }, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -344,7 +681,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 29, "metadata": { "collapsed": true }, @@ -355,7 +692,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 30, "metadata": {}, "outputs": [ { @@ -370,7 +707,7 @@ " 4 4 5 5 5 5 6" ] }, - "execution_count": 16, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -390,7 +727,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 31, "metadata": {}, "outputs": [ { @@ -407,7 +744,7 @@ " 0 7 5 6 7" ] }, - "execution_count": 17, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -425,7 +762,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 32, "metadata": {}, "outputs": [ { @@ -439,7 +776,7 @@ " 1" ] }, - "execution_count": 18, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -452,36 +789,148 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 33, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "MatchingMarkets.Matching(7, 5, \n", + " [5, 1] = true\n", + " [6, 1] = true\n", + " [7, 1] = true\n", + " [2, 2] = true\n", + " [3, 3] = true\n", + " [4, 4] = true\n", + " [1, 5] = true)" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matching = deferred_acceptance(s_prefs, c_prefs, caps)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "([5, 2, 3, 4, 1, 1, 1], [7, 6, 5, 2, 3, 4, 1], [1, 4, 5, 6, 7, 8])" + "1-element Array{Int64,1}:\n", + " 5" ] }, - "execution_count": 19, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "deferred_acceptance(s_prefs, c_prefs, caps)" + "matching(1)" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "([5, 2, 3, 4, 1, 1, 1], [7, 6, 5, 2, 3, 4, 1], [1, 4, 5, 6, 7, 8])" + "3-element Array{Int64,1}:\n", + " 5\n", + " 6\n", + " 7" ] }, - "execution_count": 20, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matching(1, inverse=true)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Dict{Int64,Array{Int64,1}} with 7 entries:\n", + " 7 => [1]\n", + " 4 => [4]\n", + " 2 => [2]\n", + " 3 => [3]\n", + " 5 => [1]\n", + " 6 => [1]\n", + " 1 => [5]" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_all_pairs(matching)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Dict{Int64,Array{Int64,1}} with 5 entries:\n", + " 4 => [4]\n", + " 2 => [2]\n", + " 3 => [3]\n", + " 5 => [1]\n", + " 1 => [5, 6, 7]" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_all_pairs(matching, inverse=true)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "MatchingMarkets.Matching(7, 5, \n", + " [5, 1] = true\n", + " [6, 1] = true\n", + " [7, 1] = true\n", + " [2, 2] = true\n", + " [3, 3] = true\n", + " [4, 4] = true\n", + " [1, 5] = true)" + ] + }, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } @@ -492,16 +941,23 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "([1, 5, 1, 1, 2, 3, 4], [1, 3, 4, 5, 6, 7, 2], [1, 4, 5, 6, 7, 8])" + "MatchingMarkets.Matching(5, 7, \n", + " [1, 1] = true\n", + " [5, 2] = true\n", + " [1, 3] = true\n", + " [1, 4] = true\n", + " [2, 5] = true\n", + " [3, 6] = true\n", + " [4, 7] = true)" ] }, - "execution_count": 21, + "execution_count": 39, "metadata": {}, "output_type": "execute_result" } @@ -528,8 +984,10 @@ }, { "cell_type": "code", - "execution_count": 22, - "metadata": {}, + "execution_count": 40, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "m, n = 11, 5;" @@ -537,7 +995,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 41, "metadata": {}, "outputs": [ { @@ -552,7 +1010,7 @@ " 2 0 0 2 5 0 4 0 3 0 0" ] }, - "execution_count": 23, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -576,7 +1034,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 42, "metadata": {}, "outputs": [ { @@ -597,7 +1055,7 @@ " 0 9 9 7 5" ] }, - "execution_count": 24, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } @@ -615,7 +1073,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 43, "metadata": { "collapsed": true }, @@ -626,36 +1084,161 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 44, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "MatchingMarkets.Matching(11, 5, \n", + " [2 , 1] = true\n", + " [5 , 1] = true\n", + " [8 , 1] = true\n", + " [10, 1] = true\n", + " [7 , 2] = true\n", + " [1 , 3] = true\n", + " [4 , 3] = true\n", + " [6 , 3] = true\n", + " [3 , 4] = true\n", + " [9 , 4] = true\n", + " [11, 5] = true)" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matching = deferred_acceptance(s_prefs, c_prefs, caps)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "([3, 1, 4, 3, 1, 3, 2, 1, 4, 1, 5], [2, 10, 8, 5, 7, 1, 6, 4, 3, 9, 11], [1, 5, 6, 9, 11, 12])" + "1-element Array{Int64,1}:\n", + " 3" ] }, - "execution_count": 26, + "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "deferred_acceptance(s_prefs, c_prefs, caps)" + "matching(4)" ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "([3, 1, 4, 3, 1, 3, 2, 1, 4, 1, 5], [2, 10, 8, 5, 7, 1, 6, 4, 3, 9, 11], [1, 5, 6, 9, 11, 12])" + "4-element Array{Int64,1}:\n", + " 2\n", + " 5\n", + " 8\n", + " 10" ] }, - "execution_count": 27, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matching(1, inverse=true)" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Dict{Int64,Array{Int64,1}} with 11 entries:\n", + " 2 => [1]\n", + " 11 => [5]\n", + " 7 => [2]\n", + " 9 => [4]\n", + " 10 => [1]\n", + " 8 => [1]\n", + " 6 => [3]\n", + " 4 => [3]\n", + " 3 => [4]\n", + " 5 => [1]\n", + " 1 => [3]" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_all_pairs(matching)" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Dict{Int64,Array{Int64,1}} with 5 entries:\n", + " 4 => [3, 9]\n", + " 2 => [7]\n", + " 3 => [1, 4, 6]\n", + " 5 => [11]\n", + " 1 => [2, 5, 8, 10]" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_all_pairs(matching, inverse=true)" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "MatchingMarkets.Matching(11, 5, \n", + " [2 , 1] = true\n", + " [5 , 1] = true\n", + " [8 , 1] = true\n", + " [10, 1] = true\n", + " [7 , 2] = true\n", + " [1 , 3] = true\n", + " [4 , 3] = true\n", + " [6 , 3] = true\n", + " [3 , 4] = true\n", + " [9 , 4] = true\n", + " [11, 5] = true)" + ] + }, + "execution_count": 49, "metadata": {}, "output_type": "execute_result" } @@ -666,22 +1249,89 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "([4, 5, 3, 1, 1, 3, 2, 3, 1, 4, 1], [4, 5, 9, 11, 7, 3, 6, 8, 1, 10, 2], [1, 5, 6, 9, 11, 12])" + "MatchingMarkets.Matching(5, 11, \n", + " [4 , 1] = true\n", + " [5 , 2] = true\n", + " [3 , 3] = true\n", + " [1 , 4] = true\n", + " [1 , 5] = true\n", + " [3 , 6] = true\n", + " [2 , 7] = true\n", + " [3 , 8] = true\n", + " [1 , 9] = true\n", + " [4 , 10] = true\n", + " [1 , 11] = true)" ] }, - "execution_count": 28, + "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "deferred_acceptance(s_prefs, c_prefs, caps, CProposing)" + "matching = deferred_acceptance(s_prefs, c_prefs, caps, CProposing)" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Dict{Int64,Array{Int64,1}} with 5 entries:\n", + " 4 => [1, 10]\n", + " 2 => [7]\n", + " 3 => [3, 6, 8]\n", + " 5 => [2]\n", + " 1 => [4, 5, 9, 11]" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_all_pairs(matching)" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Dict{Int64,Array{Int64,1}} with 11 entries:\n", + " 2 => [5]\n", + " 11 => [1]\n", + " 7 => [2]\n", + " 9 => [1]\n", + " 10 => [4]\n", + " 8 => [3]\n", + " 6 => [3]\n", + " 4 => [1]\n", + " 3 => [3]\n", + " 5 => [1]\n", + " 1 => [4]" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_all_pairs(matching, inverse=true)" ] }, { @@ -719,7 +1369,7 @@ "metadata": { "anaconda-cloud": {}, "kernelspec": { - "display_name": "Julia 0.6.0", + "display_name": "Julia 0.6.2", "language": "julia", "name": "julia-0.6" }, @@ -727,7 +1377,7 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "0.6.0" + "version": "0.6.2" } }, "nbformat": 4, diff --git a/src/MatchingMarkets.jl b/src/MatchingMarkets.jl index 6922b6f..1d268a0 100644 --- a/src/MatchingMarkets.jl +++ b/src/MatchingMarkets.jl @@ -1,9 +1,11 @@ module MatchingMarkets +include("types.jl") include("util.jl") include("deferred_acceptance.jl") include("matching_tools.jl") +export Matching, TwoSidedMatchingMarket, get_all_pairs export deferred_acceptance, SProposing, CProposing export random_prefs, ReturnCaps diff --git a/src/deferred_acceptance.jl b/src/deferred_acceptance.jl index 8f181f4..38e5692 100644 --- a/src/deferred_acceptance.jl +++ b/src/deferred_acceptance.jl @@ -147,26 +147,17 @@ function deferred_acceptance(prop_prefs::Matrix{Int}, next_resps[p] += 1 end - prop_matches = zeros(Int, num_prop_caps) - resp_matches = Array{Int}(num_resp_caps) - prop_ctr = zeros(Int, num_props) - - ctr = 1 + matching = Matching(num_props, num_resps) for r in 1:num_resps for j in 1:resp_caps[r] if j <= length(bhs[r]) p = resp_prefs[bhs[r][j], r] - prop_matches[prop_indptr[p]+prop_ctr[p]] = r - prop_ctr[p] += 1 - resp_matches[ctr] = p - else - resp_matches[ctr] = 0 + matching.matching[p, r] = true end - ctr += 1 end end - return prop_matches, resp_matches, prop_indptr, resp_indptr + return matching end # One-to-one @@ -200,9 +191,7 @@ Compute a stable matching by the DA algorithm for a one-to-one matching function deferred_acceptance(prop_prefs::Matrix{Int}, resp_prefs::Matrix{Int}) prop_caps = ones(Int, size(prop_prefs, 2)) resp_caps = ones(Int, size(resp_prefs, 2)) - prop_matches, resp_matches, _, _ = - deferred_acceptance(prop_prefs, resp_prefs, prop_caps, resp_caps) - return prop_matches, resp_matches + return deferred_acceptance(prop_prefs, resp_prefs, prop_caps, resp_caps) end # Many-to-one @@ -246,13 +235,10 @@ function deferred_acceptance(s_prefs::Matrix{Int}, proposal::Type{P}=SProposing) where P<:DAProposal s_caps = ones(Int, size(s_prefs, 2)) if proposal == SProposing - s_matches, c_matches, _, indptr = - deferred_acceptance(s_prefs, c_prefs, s_caps, caps) + return deferred_acceptance(s_prefs, c_prefs, s_caps, caps) else - c_matches, s_matches, indptr, _ = - deferred_acceptance(c_prefs, s_prefs, caps, s_caps) + return deferred_acceptance(c_prefs, s_prefs, caps, s_caps) end - return s_matches, c_matches, indptr end diff --git a/src/types.jl b/src/types.jl new file mode 100644 index 0000000..6c4bc48 --- /dev/null +++ b/src/types.jl @@ -0,0 +1,105 @@ +#= +Type definitions of various matching markets. + +Author: Akira Matsushita + +=# + +import Base: getindex + + +type Matching + num_students::Int + num_schools::Int + matching::SparseMatrixCSC{Bool} +end + +function Matching(num_students::Int, num_schools::Int) + return Matching(num_students, num_schools, spzeros(Bool, num_students, num_schools)) +end + +function Base.getindex(matching::Matching, student_index::Int, school_index::Int) + if 1 <= student_index <= matching.num_students + if 1 <= school_index <= matching.num_schools + return matching.matching[student_index, school_index] + end + end + throw(BoundsError(matching.matching, (student_index, school_index))) +end + +function Base.getindex(matching::Matching, student_index::Int, school_index::Colon) + if 1 <= student_index <= matching.num_students + return matching.matching[student_index, :] + end + throw(BoundsError(matching.matching, (student_index, school_index))) +end + +function Base.getindex(matching::Matching, student_index::Colon, school_index::Int) + if 1 <= school_index <= matching.num_schools + return matching.matching[:, school_index] + end + throw(BoundsError(matching.matching, (student_index, school_index))) +end + +function (matching::Matching)(index::Int; inverse::Bool=false) + # student index case + if inverse == false + if index < 1 || matching.num_students < index + throw(BoundsError(matching.matching, (index, :))) + end + sparse_schools, sparse_bools = findnz(matching.matching[index, :]) + schools = Vector{Int}() + for (s, bool) in zip(sparse_schools, sparse_bools) + if bool + Base.push!(schools, s) + end + end + return schools + # school index case + else + if index < 1 || matching.num_schools < index + throw(BoundsError(matching.matching, (:, index))) + end + sparse_students, sparse_bools = findnz(matching.matching[:, index]) + students = Vector{Int}() + for (s, bool) in zip(sparse_students, sparse_bools) + if bool + Base.push!(students, s) + end + end + return students + end +end + +function get_all_pairs(matching::Matching; inverse::Bool=false) + pairs = Dict{Int, Vector{Int}}() + students, schools, bools = findnz(matching.matching) + + # student -> schools + if inverse == false + for i in 1:matching.num_students + pairs[i] = Vector{Int}() + end + for (student, school, bool) in zip(students, schools, bools) + if bool + Base.push!(pairs[student], school) + end + end + # school -> students + else + for i in 1:matching.num_schools + pairs[i] = Vector{Int}() + end + for (student, school, bool) in zip(students, schools, bools) + if bool + Base.push!(pairs[school], student) + end + end + end + return pairs +end + + + + +