조합 최적화로 몇 코로 풀기

Advent Calendar 18 일 기사 조합 최적화로 사각형으로 조각을 풀기
Advent Calendar 20 일 기사 조합 최적화로 빌딩 해결

이게 뭐야



몇 콜로를 Python으로 조합 최적화 모델을 만들어 풀어줍니다.
푸는 재미는 모델링을 고안하는 것입니다.

자신도 시도하고 싶은 사람은 아래를 참조하십시오.
  • 스도쿠를 통해 조합 최적화를 배우자.

  • 문제


  • 모든 매스를 1~4의 숫자 또는 공백으로 합니다.
  • 숫자는 그 매스의 인접 매스에 숫자가 들어가는 매스의 수가 됩니다.
  • 같은 숫자를 연속해서는 안됩니다.
  • 모든 숫자를 연결한다.

  • 아래는 왼쪽이 문제이고 오른쪽이 대답입니다.



    입력 파라미터


    data 에 힌트가 들어 있다고 합니다.

    파이썬
    import numpy as np
    from itertools import chain, product
    from pulp import LpProblem, lpSum, lpDot, value
    from ortoolpy import addvars, addbinvars
    data = """\
    ..1...1
    .1.3.32
    .......
    .2.4.4.
    .......
    31.1.3.
    1...1..""".splitlines()
    nw, nh = len(data[0]), len(data)
    

    파이썬으로 풀기



    수리 모델을 만들고 풀어 봅시다.

    변수


  • v:0:white, 1-4:number (1)
  • r:숫자 (2)

  • 제약


  • 숫자가 있으면 그 숫자 (3)
  • 숫자는 1개 (4)
  • r을 v로 표현 (5)
  • 숫자는 주변 숫자의 수와 같습니다 (6)
  • 같은 숫자는 연속해서는 안됩니다 (7)
  • 모든 숫자가 연결됨 (8)

  • 파이썬
    m = LpProblem()
    v = np.array(addbinvars(nh, nw, 5)) # 0:white, 1-4:number (1)
    u = np.zeros((nh+2, nw+2), dtype=object)
    u[1:-1,1:-1] = v[:,:,1:].sum(2)
    w = u[1:-1,2:]+u[1:-1,:-2]+u[2:,1:-1]+u[:-2,1:-1]
    r = np.array(addvars(nh, nw)) # (2)
    for i, j in product(range(nh), range(nw)):
        if data[i][j].isdigit():
            m += v[i,j,int(data[i][j])] == 1 # (3)
        m += lpSum(v[i,j]) == 1 # (4)
        m += lpDot(range(5), v[i,j]) == r[i,j] # (5)
        m += w[i,j] >= r[i,j] # (6)
        m += w[i,j] <= r[i,j] + 4*v[i,j,0] # (6)
    for k in range(1, 5):
        for e in chain((v[1:,:,k]+v[:-1,:,k]).flat, (v[:,1:,k]+v[:,:-1,k]).flat):
            m += e <= 1 # (7)
    while True:
        m.solve()
        s = np.vectorize(value)(r).astype(int)
        break
        if unionfind.isconnected(s==0):
            break
        m += lpSum(v[r==0]) >= 1 # (8)
    

    결과 표시



    파이썬
    t = s.astype(str)
    t[s==0] = '.'
    print('\n'.join(' '.join(s) for s in t))
    >>>
    1 . 1 2 . . 1
    3 1 . 3 2 3 2
    2 . . 2 . 2 .
    3 2 3 4 2 4 1
    2 . 2 3 . 2 .
    3 1 . 1 . 3 1
    1 . . . 1 2 .
    

    풀리고 있는지 확인할 수 있습니다.

    이상

    좋은 웹페이지 즐겨찾기