파이톤의 수리 최적화 구해기를 시험해 봤어요.


python의 수리적 최적화solver,pup,cxvpy를 사용하여 해봤기 때문에 필기를 남겼습니다.
코드는 여기요.
이번 샘플 문제는 아래 사이트를 참고하였다.
http://www.nct9.ne.jp/m_hiroi/light/pulp01.html
공장(x, y)에서 상점(a, b, c)으로 상품을 발송합니다.
공급량, 수요량, 운송 원가는 다음 표에서 제시할 때 총 운송 원가가 가장 적은 조건을 요구한다.
표: 운송 원가
상점
상점
상점
공급량
공장
10
6
16
8
공장
8
8
4
16
수요량
12
4
8
데이터 프레임에서 위의 테이블을 사용합니다.

pulp


최적화 문제의 명칭을 설정하고 최소화(최대화) 문제를 설정합니다.
문제를 최대화하는 상황에서pulp.매개변수에 LpMaximize 를 넣습니다.
가게 이름(가게 a, 가게 b, 가게 c)을 목록화하다.
import pulp

prob = pulp.LpProblem('sample', # 問題の名称
                      pulp.LpMinimize) # 最小化。なおデフォルトは最小化
변수를 설정합니다.
item_list = ["a", "b", "c"]
공장 x에서 상점 a에 보내는 상품의 양은xa로 이렇게 하나하나 변수를 설정해도 되지만 번거롭기 때문에 포장 표시를 사용해야 한다.
부분 생략 후 발췌
# 工場Xの供給量
fact_x = [pulp.LpVariable(f'fact_x_{i}', 
                    lowBound = 0, # 下限値。デフォルト値はNone
                    upBound=None, # 上限値。デフォルト値はNone
                    cat=pulp.LpContinuous
                         # 変数の種類。デフォルトは"Continuous"(連続値)
                         # 他には pulp.LpInteger 整数、pulp.LpBinary バイナリ値
                    ) for i in shop_list]
.
변수의 pup을 지정합니다.LpVariable 내의 변수 이름에 포맷된 문자열을 사용하고 for문에 목록shop을 추가합니다리스트에 있는 ["a", "b", "c"]를 한 번 넣어주세요.a、x_b、x_변수 c를 만듭니다.
공장 y의 공급량도 마찬가지다.
[pulp.LpVariable(
    f"x_{i}" # 変数名。
    ) for i in shop_list]
목적 변수를 설정합니다.
# 工場yの供給量
fact_y = [pulp.LpVariable(f'fact_y_{i}', 
                    lowBound = 0, # 下限値。デフォルト値はNone
                    upBound=None, # 上限値。デフォルト値はNone
                    cat=pulp.LpContinuous
                         # 変数の種類。デフォルトは"Continuous"(連続値)
                         # 他には pulp.LpInteger 整数、pulp.LpBinary バイナリ値
                    ) for i in shop_list]
제약조건을 설정합니다.
수요량
prob += pulp.lpSum(fact_x * df.iloc[0, :3]) + pulp.lpSum(fact_y * df.iloc[1, :3])
공급량
for i in range(3):
    prob += fact_x[i] + fact_y[i] >= df.iloc[2, i]
실행
prob += pulp.lpSum(fact_x) <= df["供給量"][0]
prob += pulp.lpSum(fact_y) <= df["供給量"][1]
Status Optimal
실행 결과 상태
의향
'Undefined'
이 가능하다, ~할 수 있다,...
'Unbounded'
비유계.무한치가 가능하기 때문에 최선의 해답은 존재하지 않는다
'Infeasible'
실행할 수 없다.제약조건이 충족되지 않은 솔루션
'Not Solved'
미해결
'Optimal'
최적의 해결 방안이 존재하다
https://stackoverflow.com/questions/24167958/what-does-pulp-lpstatus-undefined-actually-mean
데이터 프레임으로 결과 표시하기
status = prob.solve()
print("Status", pulp.LpStatus[status])

최소화된 대상 함수
result = pd.DataFrame(
    [
        [fact_x[i].value() for i in range(3)],
        [fact_y[i].value() for i in range(3)],
    ],
    columns=["店a", "店b", "店c"],
    index=["工場x", "工場y"]
)
160.0

cxvpy


cxvpy는pup과 달리 변수의 원소수를 지정할 수 있습니다.
prob.objective.value()
cp.Variable(3)는원소수3의변수를,cp.Variable(3,4)는3D원소수의변수를 설정할 수 있습니다.
import cvxpy as cp

fact_x = cp.Variable(
                    len(shop_list), # 要素数。2次元の場合は(x, y)と設定する
                    integer=False, # 整数の場合はTrueとする
                    boolean=False, # Binary値の場合はTrueとする
                    pos=True # 正の数
                    )
목적 변수의 설정과 최소화 또는 최대화 설정
fact_y = cp.Variable(
                    len(shop_list), # 要素数。2次元の場合は(x, y)と設定する
                    integer=False, # 整数の場合はTrueとする
                     boolean=False, # Binary値の場合はTrueとする
                    pos=True # 正の数
                    )
요구량
cxvpx의 제약조건은 다음과 같습니다.
첫 번째 변수 = [(같음) 좌식>= 우식]
두 번째 이후 변수 + = [(더하기) 왼쪽] = 오른쪽]
그럴 필요가 있을 것 같다.
이번처럼 for문을 사용했기 때문에 첫 번째~세 번째 총결산은 좀 번거롭지만 아래처럼 변수=[]로 하는 것이 좋습니다.
exp = cp.sum(fact_x * df.iloc[:1, :3].squeeze() + fact_y * df.iloc[1:2, :3].squeeze())
obj = cp.Minimize(exp) # 最大化のときはcp.Maximize()
공급량
const = []

for i in range(3):
    const += [fact_x[i] + fact_y[i] >= df.iloc[2, i]]
문제(목적 변수/제약 조건)의 설정과 집행
const += [cp.sum(fact_x) <= df["供給量"][0]]
const += [cp.sum(fact_y) <= df["供給量"][1]]
표시 변수
소수점 이하의 상세한 숫자를 표시하기 때문에 소수점 이하 15자리 정도까지 표시하도록 설정했습니다.
prob = cp.Problem(obj, const)
status = prob.solve(verbose=True)
pd.options.display.precision = 15

최소 목표 변수의 출력
result = pd.DataFrame(
    [
        [fact_x[i].value for i in range(3)],
        [fact_y[i].value for i in range(3)],
    ],
    columns=["店a", "店b", "店c"],
    index=["工場x", "工場y"]
)

pup과 cxvpy의 차이


pulp
https://coin-or.github.io/pulp/index.html
  • 는 선형 계획만 확정할 수 있다.
    cxvpy
    https://www.cvxpy.org/index.html
  • 선형 계획뿐만 아니라 비선형 계획도 얻을 수 있다.
  • 수리 최적화를 배울 수 있는 사이트 문서


  • 웹 페이지 정보
    https://www.miyamotolab.org/lectures/autumn_winter

  • 동경공업대학 수야연구소 사이트
    http://www.me.titech.ac.jp/~mizu_lab/text.html

  • 파이썬 그래픽 삽입 알고리즘 입문
    http://www.orsj.or.jp/archive2/or63-12/or63_12_762.pdf

  • 정수 계획법의 공식화 입문
    http://web.tuat.ac.jp/~miya/fujie_ORSJ.pdf
  • 이상은 끝까지 읽어주셔서 감사합니다.

    좋은 웹페이지 즐겨찾기