조합 최적화로 몇 코로 풀기
Advent Calendar 20 일 기사 조합 최적화로 빌딩 해결
이게 뭐야
몇 콜로를 Python으로 조합 최적화 모델을 만들어 풀어줍니다.
푸는 재미는 모델링을 고안하는 것입니다.
자신도 시도하고 싶은 사람은 아래를 참조하십시오.
문제
아래는 왼쪽이 문제이고 오른쪽이 대답입니다.
입력 파라미터
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)
파이썬으로 풀기
수리 모델을 만들고 풀어 봅시다.
변수
제약
파이썬
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 .
풀리고 있는지 확인할 수 있습니다.
이상
Reference
이 문제에 관하여(조합 최적화로 몇 코로 풀기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/SaitoTsutomu/items/3b61cf7232cfac25bff3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)