조합 최적화로 오노 풀기
이게 뭐야
오노 을 파이썬에서 조합 최적화 모델을 만들어 풀어 라.
푸는 재미는 모델링을 고안하는 것입니다.
자신도 시도하고 싶은 사람은 아래를 참조하십시오.
문제
아래는 왼쪽이 문제이고 오른쪽이 대답입니다.
입력 파라미터
data
에 힌트가 들어 있다고 합니다.파이썬
import numpy as np
from itertools import product
from pulp import LpProblem, lpSum, value
from ortoolpy import addvars, addbinvars
data = """\
4...
3...
...*
*23.""".splitlines()
n = len(data)
파이썬으로 풀기
수리 모델을 만들고 풀어 봅시다.
공식화
\begin{array}{cl}
変数 & x_{ij} \in \{0, 1\} ~ \forall i, j ~ ~ ~ マスi,jが青●か (1) \\
変数 & y_{ijk} \ge 0 ~ \forall i, j, k ~ ~ ~ マスi,jの方向kの青●連続数 (2) \\
\mbox{subject to} & yをxで表す (3) \\
& 数字や*の指定 (4) \\
& 単独青●の禁止 (5) \\
\end{array}
파이썬
def cons(m,x,y,i,j,k,dx,dy,bdi,bdj):
if i == bdi or j == bdj:
m += y[i,j,k] == 0 # (3)
else:
m += y[i,j,k] <= y[i+dx,j+dy,k]+1 # (3)
m += y[i,j,k] <= x[i+dx,j+dy]*(n-1) # (3)
m += y[i,j,k] >= y[i+dx,j+dy,k]+1 - n*(1-x[i+dx,j+dy]) # (3)
m = LpProblem()
x = np.array(addbinvars(n, n)) # 青●か (1)
y = np.array(addvars(n, n, 4)) # 縦、横、上右下左の連続数 (2)
m += lpSum(x) # (3)
for i, j in product(range(n),range(n)):
cons(m,x,y,i,j,0,-1, 0, 0,-1)
cons(m,x,y,i,j,1, 0, 1, -1,n-1)
cons(m,x,y,i,j,2, 1, 0,n-1,-1)
cons(m,x,y,i,j,3, 0,-1, -1,0)
if data[i][j] == '*':
m += x[i,j] == 0 # (4)
elif data[i][j].isdigit():
m += x[i,j] == 1 # (4)
m += lpSum(y[i,j]) == int(data[i][j]) # (4)
else:
m += lpSum(y[i,j]) >= x[i,j]
m.solve()
결과 표시
파이썬
print(np.vectorize(value)(x).astype(int))
>>>
[[1 1 1 0]
[1 1 0 0]
[1 0 1 0]
[0 1 1 1]]
풀리고 있는지 확인할 수 있습니다.
요약
퍼즐이라는 테마로 조합 최적화는 어땠습니까?
「재미있어! 해보자!」라고 느끼실 수 있으면 다행입니다.
이상
Reference
이 문제에 관하여(조합 최적화로 오노 풀기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/SaitoTsutomu/items/b1cc4e123245ea56ee18텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)