小住真央のデモノートです。コードはこちら


In [1]:
using MyMatching

testを実行します。


In [2]:
Pkg.test("MyMatching")


INFO: Testing MyMatching
Test Summary:               | Pass  Total
Testing deferred acceptance |   18     18
INFO: MyMatching tests passed

ShingakuMatchingを用いて進学選択シミュレーションを行います。


In [3]:
using ShingakuMatching

departments = get_departments()

num_students = 300 #number of students
students = get_students(num_students)

prop_prefs, resp_prefs, caps = get_random_prefs(students, departments)


Out[3]:
(Array{Int64,1}[[23, 6, 56, 102, 77, 83, 123, 45, 51, 129  …  35, 75, 145, 148, 19, 116, 9, 84, 25, 27], [95, 89, 27, 54, 29, 126, 58, 128, 101, 118  …  151, 4, 31, 139, 49, 98, 91, 132, 102, 90], [100, 102, 76, 26, 34, 124, 56, 122, 58, 54  …  62, 36, 43, 20, 21, 40, 27, 138, 86, 123], [113, 145, 107, 37, 47, 97, 60, 142, 6, 79  …  85, 56, 105, 146, 25, 126, 136, 13, 118, 62], [18, 86, 102, 22, 14, 64, 10, 46, 126, 37  …  123, 47, 43, 27, 44, 60, 36, 61, 33, 30], [127, 132, 62, 15, 126, 58, 106, 91, 51, 134  …  6, 27, 86, 39, 33, 43, 49, 146, 29, 13], [142, 140, 111, 131, 54, 114, 41, 23, 35, 144  …  119, 81, 13, 51, 67, 139, 39, 125, 120, 109], [24, 41, 49, 42, 72, 56, 11, 74, 65, 112  …  66, 102, 22, 51, 62, 37, 52, 23, 38, 141], [45, 19, 34, 100, 60, 74, 64, 84, 18, 122  …  112, 50, 65, 49, 58, 121, 70, 48, 47, 124], [2, 86, 74, 53, 84, 124, 15, 123, 120, 97  …  19, 7, 138, 21, 17, 102, 47, 39, 121, 143]  …  [100, 31, 121, 3, 49, 51, 16, 86, 55, 40  …  22, 46, 76, 45, 25, 61, 13, 26, 11, 30], [15, 122, 71, 27, 25, 86, 96, 8, 111, 126  …  128, 33, 29, 145, 77, 45, 9, 146, 131, 84], [113, 79, 51, 84, 146, 126, 90, 132, 11, 101  …  21, 142, 130, 137, 145, 75, 62, 128, 129, 87], [78, 31, 142, 39, 97, 130, 126, 94, 121, 37  …  86, 19, 54, 77, 128, 80, 103, 148, 6, 11], [139, 140, 75, 56, 19, 108, 25, 83, 102, 135  …  116, 126, 8, 99, 47, 124, 23, 96, 60, 31], [12, 126, 57, 9, 32, 52, 58, 41, 35, 65  …  15, 46, 60, 25, 130, 30, 40, 24, 27, 13], [1, 17, 27, 112, 97, 122, 126, 120, 86, 130  …  19, 15, 51, 9, 72, 56, 21, 25, 47, 141], [130, 75, 43, 11, 17, 77, 146, 148, 100, 96  …  71, 23, 62, 8, 31, 81, 99, 142, 29, 137], [58, 130, 33, 19, 17, 37, 112, 122, 29, 143  …  121, 23, 43, 51, 97, 120, 74, 45, 102, 27], [16, 120, 13, 31, 48, 27, 45, 22, 100, 40  …  47, 50, 124, 58, 38, 51, 23, 14, 39, 19]], Array{Int64,1}[[209, 86, 199, 171, 240, 208, 95, 170, 34, 212  …  224, 290, 138, 180, 54, 267, 197, 164, 68, 179], [215, 98, 142, 28, 134, 276, 38, 16, 257, 104  …  10, 35, 288, 49, 151, 161, 285, 129, 145, 105], [82, 169, 30, 178, 250, 213, 242, 41, 216, 55  …  52, 289, 92, 60, 217, 21, 44, 167, 136, 3], [121, 66, 248, 261, 153, 207, 173, 40, 13, 268  …  2, 133, 74, 71, 72, 88, 93, 112, 239, 4], [269, 218, 192, 128, 126, 110, 252, 99, 182, 234  …  62, 165, 174, 163, 42, 175, 32, 158, 117, 127], [93, 192, 262, 158, 237, 36, 131, 126, 39, 40  …  146, 191, 94, 159, 72, 205, 256, 2, 74, 100], [200, 16, 279, 28, 69, 10, 219, 98, 161, 257  …  115, 142, 90, 253, 35, 81, 288, 15, 80, 111], [245, 33, 294, 162, 153, 191, 192, 246, 66, 57  …  14, 234, 132, 239, 198, 207, 284, 261, 63, 70], [81, 103, 276, 96, 264, 195, 5, 92, 202, 215  …  158, 128, 242, 66, 48, 201, 245, 160, 204, 223], [53, 260, 238, 255, 136, 3, 216, 61, 259, 242  …  178, 21, 41, 217, 241, 176, 48, 201, 82, 221]  …  [70, 205, 64, 271, 100, 131, 128, 191, 106, 246  …  117, 114, 46, 25, 7, 225, 218, 139, 6, 175], [260, 92, 290, 244, 215, 15, 212, 119, 142, 123  …  273, 176, 291, 178, 111, 216, 90, 55, 154, 224], [163, 147, 156, 112, 232, 118, 18, 63, 127, 293  …  160, 228, 139, 59, 298, 29, 108, 133, 72, 272], [272, 247, 189, 155, 186, 126, 266, 108, 185, 160  …  177, 198, 163, 153, 57, 237, 112, 295, 168, 203], [50, 198, 210, 261, 157, 91, 20, 281, 248, 59  …  294, 29, 6, 272, 78, 181, 40, 25, 75, 193], [229, 118, 165, 247, 126, 158, 182, 284, 106, 1  …  172, 203, 127, 194, 135, 192, 7, 146, 252, 110], [261, 153, 162, 62, 292, 110, 46, 36, 147, 263  …  88, 108, 239, 94, 106, 229, 100, 196, 70, 4], [162, 67, 283, 225, 78, 37, 232, 147, 222, 22  …  46, 256, 266, 114, 185, 157, 183, 70, 141, 187], [173, 177, 19, 210, 165, 268, 196, 155, 247, 39  …  166, 185, 131, 266, 32, 195, 93, 194, 121, 258], [281, 156, 4, 72, 88, 248, 18, 153, 64, 133  …  31, 191, 274, 207, 261, 139, 293, 75, 66, 173]], [118, 1, 1, 1, 1, 2, 81, 3, 18, 3  …  7, 3, 6, 2, 6, 8, 24, 33, 8, 6])

In [4]:
prop_matched, resp_matched, indptr = my_deferred_acceptance(prop_prefs, resp_prefs, caps)


Out[4]:
([102, 95, 100, 113, 18, 127, 142, 24, 45, 84  …  121, 122, 113, 78, 56, 12, 1, 130, 58, 16], [297, 47, 179, 0, 0, 0, 0, 0, 0, 0  …  0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 119, 120, 121, 122, 123, 125, 206, 209, 227  …  881, 884, 890, 892, 898, 906, 930, 963, 971, 977])

以下では、どの生徒ともマッチングしなかった学科を探します。


In [9]:
r = 1
while r <= length(resp_prefs)
    if (resp_matched[indptr[r]:indptr[r+1]-1] == [0])
        println("resp $r ""got no student.")
    end
    r += 1
end


resp 4 got no student.
resp 5 got no student.
resp 22 got no student.
resp 32 got no student.

実際に上記の学科のresp_matchedが0になっているかどうかを確認してみます。


In [10]:
j = 4
resp_matched[indptr[j]:indptr[j+1]-1]


Out[10]:
1-element Array{Int64,1}:
 0

In [11]:
j = 5
resp_matched[indptr[j]:indptr[j+1]-1]


Out[11]:
1-element Array{Int64,1}:
 0

In [12]:
j = 22
resp_matched[indptr[j]:indptr[j+1]-1]


Out[12]:
1-element Array{Int64,1}:
 0

In [13]:
j = 32
resp_matched[indptr[j]:indptr[j+1]-1]


Out[13]:
1-element Array{Int64,1}:
 0

次に、各学科が受け入れた学生の数を調べます。


In [39]:
resp_num = Vector{Int}(length(resp_prefs))
for u in 1:length(resp_prefs)
    u_matched = resp_matched[indptr[u]:indptr[u+1]-1]
    stu_num = 1
    while !(u_matched[stu_num] == 0)
        stu_num += 1
        if stu_num > length(u_matched)
            break
        end
    end
    resp_num[u] = stu_num -1
end

resp_num


Out[39]:
151-element Array{Int64,1}:
 3
 1
 1
 0
 0
 2
 3
 3
 6
 0
 3
 1
 2
 ⋮
 2
 1
 5
 3
 3
 0
 2
 0
 6
 1
 4
 0

最も多くの学生を受け入れた学科を探します。


In [48]:
maximum(resp_num)


Out[48]:
12

In [49]:
for max_resp in 1:length(resp_prefs)
    if !(resp_num[max_resp] == maximum(resp_num))
        max_resp += 1
    else
        print(max_resp)
        break
    end
end


122

最も多くの学生を受け入れた学科122と学生とのマッチングに着目します。

学科122に内定した学生が、学科1を何番目に志望していたかを、以下の関数を使ってみてみます。


In [50]:
function student_pref_rank(resp_number)
    x = 1
    while x <= num_students
        if x in resp_matched[indptr[resp_number]:indptr[resp_number+1]-1]
            pref_rank = 1
            x_pref = prop_prefs[x]
            while !(x_pref[pref_rank] == resp_number)
                pref_rank += 1
            end
            println("student $x; ""pref_rank = $pref_rank")
        end
        x += 1
    end
end


Out[50]:
student_pref_rank (generic function with 1 method)

In [51]:
student_pref_rank(122)


student 26; pref_rank = 3
student 27; pref_rank = 4
student 49; pref_rank = 2
student 107; pref_rank = 2
student 144; pref_rank = 2
student 170; pref_rank = 3
student 171; pref_rank = 2
student 178; pref_rank = 7
student 194; pref_rank = 1
student 248; pref_rank = 1
student 273; pref_rank = 1
student 292; pref_rank = 2

今度は学科122に内定した学生が、学科122の受け入れ順位の何番目に位置していたかを、以下の関数を使ってみてみます。


In [56]:
function student_resp_rank(resp_number)
    w = resp_matched[indptr[resp_number]:indptr[resp_number+1]-1]
    for y in 1: caps[resp_number]
        if !(w[y] == 0) 
            resp_rank = 1
            pref = resp_prefs[resp_number]
            while !(pref[resp_rank] == w[y])
                resp_rank += 1
            end
            stu = w[y]
            println("student $stu; ""resp_rank = $resp_rank")
        else
            break
        end
    end
end


Out[56]:
student_resp_rank (generic function with 1 method)

In [57]:
student_resp_rank(122)


student 194; resp_rank = 206
student 248; resp_rank = 95
student 273; resp_rank = 199
student 49; resp_rank = 210
student 107; resp_rank = 228
student 144; resp_rank = 285
student 292; resp_rank = 143
student 171; resp_rank = 286
student 178; resp_rank = 263
student 26; resp_rank = 34
student 27; resp_rank = 207
student 170; resp_rank = 104

ここから、学科122に内定した学生にとって、学科122は選好順位が比較的高く魅力的であった一方で、学科122に内定した学生は、学科122から見てさほど魅力的ではなかったと言えそうです。

以上で検証を終わります。