조합 최적화로 부등식 풀기

Advent Calendar 21 일 기사 조합 최적화로 혼자 해줘.
Advent Calendar 23 일 기사 조합 최적화로 파급 효과 해결

이게 뭐야



부등식을 파이썬에서 조합 최적화 모델을 만들어 풀어 라.
푸는 재미는 모델링을 고안하는 것입니다.

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

  • 문제


  • 각 흰색 매스에는 1에서 n까지의 숫자가 하나만 들어갑니다
  • 각 가로 행과 각 세로 열에는 동일한 숫자가 없습니다
  • 두 개의 연속 칸 사이에 부등호가있는 경우, 칸에 들어가는 숫자는 부등호가 나타내는 대소 관계를 충족시켜야합니다.

    아래는 왼쪽이 문제이고 오른쪽이 대답입니다. 이 문제에 대한 해결책은 여러 가지가 있습니다.



    입력 파라미터


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

    파이썬
    import numpy as np
    from pulp import LpProblem, lpSum, lpDot, value
    from ortoolpy import addvars, addbinvars
    data = """\
    . 1 . 3 .
    
    . 3<. . .
    
    .<. . . 5
    V   A    
    2 . . . .
        A   A
    .<.<4<.>.""".splitlines()
    n = (len(data)+1)//2
    

    파이썬으로 풀기



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

    변수


  • v: 각 위치가 어느 숫자인지 (1)
  • r: 각 위치의 숫자 (2)

  • 제약


  • $v_{ij}$는 하나의 숫자만 (3)
  • r을 v로 표현 (4)
  • 세로 또는 가로에 같은 숫자가 없습니다 (5)
  • 숫자가 지정되면 숫자가됩니다 (6)
  • 부등호가 있으면 그 관계를 만족시킨다 (7)

  • 파이썬
    m = LpProblem()
    v = np.array(addbinvars(n, n, n)) # (1)
    r = np.array(addvars(n, n)) # (2)
    for i in range(n):
        for j in range(n):
            m += lpSum(v[i,j]) == 1 # (3)
            m += lpDot(range(n), v[i,j]) + 1 == r[i,j] # (4)
            m += lpSum(v[i,:,j]) == 1 # (5)
            m += lpSum(v[:,i,j]) == 1 # (5)
            c = data[i*2][j*2]
            if c.isdigit():
                m += v[i,j,int(c)-1] == 1 # (6)
    for i in range(n - 1):
        for j in range(n):
            c = data[i*2+1][j*2]
            if c == 'A':
                m += r[i,j] <= r[i+1,j] - 1 # (7)
            elif c == 'V':
                m += r[i,j] >= r[i+1,j] + 1 # (7)
    for i in range(n):
        for j in range(n - 1):
            c = data[i*2][j*2+1]
            if c == '<':
                m += r[i,j] <= r[i,j+1] - 1 # (7)
            elif c == '>':
                m += r[i,j] >= r[i,j+1] + 1 # (7)
    m.solve()
    

    결과 표시



    파이썬
    print(np.vectorize(value)(r).astype(int))
    >>>
    [[5 1 2 3 4]
     [4 3 5 1 2]
     [3 4 1 2 5]
     [2 5 3 4 1]
     [1 2 4 5 3]]
    

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

    이상

    좋은 웹페이지 즐겨찾기