조합 최적화로 학군 편성 문제 해결

이게 뭐야



12/2 에 행해진 최적화 의 세미나 Gurobi Optimizer 솔루션 세미나 2016 그리고, 학교의 학구 결정을 다품종 최소 비용 흐름 문제 로서 풀 수 있는 것을 들었으므로 실제로 해 보았습니다.

  • 현별 데이터의 시각화 라이브러리 japanmap을 사용합니다.
  • 혼슈의 34도부현을 대상으로 하고, 1현에 1명 학생이 있다고 합니다.
  • 아오모리, 야마나시, 야마구치에 학교가 있고, 정원은 각각 7, 21, 6명으로 합니다.
  • 인접 현으로의 이동 시간은 1로 합니다.
  • 각 학생이 3개의 학교 중 하나에 다니기로 하고, 전학생의 총 이동 시간을 최소화하는 학구의 할당을 요구합니다.

  • 사고방식


  • 34 도부현의 수요점을 작성합니다.
  • 아오모리, 야마나시, 야마구치의 수요를 각각(자신을 제외한) 6, 20, 5, 그 외는 -1로 합니다.
  • 아오모리, 야마나시, 야마구치를 대표로 하는 3개의 일본(녹일본, 청일본, 적 일본)을 생각해, 이 각 일본 중에서 인접시킵니다. (다품종 네트워크)
  • 대표점 이외의 수요점으로부터 3개의 일본의 같은 현에 링크를 합니다.
  • 대표점의 수요점에, 그 대표점을 대표로 하는 각 일본의 같은 현으로부터 링크를 합니다.



  • 이 네트워크에서 최소 비용 흐름 문제를 해결합니다.

    파이썬으로 시도



    python3
    import numpy as np, networkx as nx
    from japanmap import adjacent, pref_code, pref_map
    本州 = np.arange(2,36)
    代表点 = {pref_code('青森'):7, pref_code('山梨'):21, pref_code('山口'):6}
    # グラフ作成
    g = nx.DiGraph()
    g.add_nodes_from(本州, demand=-1)
    for i, d in 代表点.items():
        nwl = i*100
        g.node[i]['demand'] = d-1
        g.add_nodes_from(nwl+本州, demand=0)
        g.add_edge(nwl+i,i)
        g.add_edges_from((j,nwl+j) for j in 本州 if j not in 代表点)
        g.add_edges_from(((nwl+j,nwl+k) for j in 本州 for k in adjacent(j)), weight=1)
    r = nx.min_cost_flow(g)
    # 結果表示
    dc = dict(zip(代表点,['red','green','blue']))
    dc.update({i:dc[j//100]for i, t in r.items() for j, v in t.items() if v and i < 100})
    pref_map(本州, cols=[dc[i] for i in 本州], width=4)
    



    생각대로 풀었습니다.

    발전



    현실에는 여러 가지 요소를 고려해야합니다.
  • 가능한 한 이전과 동일한 학군이 바람직하다.
  • 특정한 곳에서 반드시 하고 싶다.
  • 홉 수가 아닌 거리로 한다.
  • 그룹의 수는 정확하지 않습니다.

  • 정식화를 고치면 할 수 있을 것 같습니다.

    이상

    좋은 웹페이지 즐겨찾기