"Python実践データ分析100本ノック"、この本を進めていて少し理解に時間がかかったところをメモしておきます。
リンク
最適化問題とは?
条件を満たす解の中で一番よいものを求める問題。みたいなこと。
書籍では、倉庫から工場の商品1つあたりの輸送コスト、df_tc
があり、
Fが工場、Wが倉庫を表す。
各工場の需要量、各倉庫の在庫数を制限とし、総輸送コストが最も低くなる最適化問題を紹介していた。
ortoolpy, pulpのインストール
anacondaには数理モデルライブラリが入ってないようなので、pipでインストールします。
$ pip3 install pulp $ pip3 install ortoolpy
数理モデルを使用して解を求める
import numpy as np import pandas as pd from itertools import product from pulp import LpVariable, lpSum, value from ortoolpy import model_min, addvars, addvals # 数理モデル作成 最小化するモデル m1 = model_min() # 解決する変数の定義 (3行 * 4列の座標位置(配送ルート)に対する配送量を格納するdictionary) for i in range(3): for j in range(4): v1 = {(i,j):LpVariable("v%d_%d"%(i,j),lowBound=0)} # 目的関数の定義 輸送ルートコストと(変数:倉庫から工場への配送量)の積の和(総コスト)が最小となるモデル。ここでは変数v1、最小のコストになる各倉庫から工場に対しての輸送量を求める m1 += lpSum(df_tc.iloc[i][j]*v1[i,j] for i,j in pr) # 制約条件 結果の数量は各制約を満たす数量でなければならない for i in range(3): m1 += lpSum(v1[i,j] for j in range(4)) <= 在庫表.iloc[0][i] for j in range(4): m1 += lpSum(v1[i,j] for i in range(3)) >=需要表.iloc[0][j] # solveでこの変数v1が解決される m1.solve() #倉庫から工場への輸送量を表現するのDataFrame df_tr_sol = df_tc.copy() total_cost = 0 # 結果はitems()で取得できる kに変数名の引数(この場合、座標)、xに計算された数量が入る for k,x in v1.items(): i,j = k[0],k[1] df_tr_sol.iloc[i][j] = value(x) total_cost += df_tc.iloc[i][j]*value(x)
この部分が理解するのに時間がかかった(^_^;) 各コストに対しての数量を座標に応じた空変数として用意し、solveで数量を解決する。といったイメージだと思う。
for i in range(3): for j in range(4): v1 = {(i,j):LpVariable("v%d_%d"%(i,j),lowBound=0)} m1 += lpSum(df_tc.iloc[i][j]*v1[i,j] for i,j in pr)
理解の参考になったページ: チーム内の業務割当てをPython + PuLPで最適化 - 昭和生まれ30代経理マンが令和に始めたBlog
リンク