.. -*- coding: utf-8 -*- 集約・複数の添字 ---------------- コスト定義式:: # 運転コスト/週(目的関数) problem += costX[0]*x[0] + costX[1]*x[1], '全運転コスト' は,すべての油田について運転コストの和をとるという意味なので, これを一般的に記述すると,以下のようになります. .. math:: \sum_i{costX_i \cdot x_i} 対応する PySIMPLE の記述は,以下のようになります.:: Sum(costX[i]*x[i], i) ``Sum()`` は :math:`\displaystyle \sum` に対応する関数で,:: Sum(和をとる式, 添字) の書式を持ちます. 次にノルマ制約についても,Sum() を適用したいと考えますが,旧記述では,:: # 製品ノルマ problem += 6*x[0] + x[1] >= norma['重油'], '重油ノルマ/週' problem += 4*x[0] + 6*x[1] >= norma['ガス'], 'ガスノルマ/週' と各油田の生産量が直接数値で記述されているので,一般化できません. そこで,定式化において定数 :math:`prodX_{i,j}` を導入し,制約式を次のように記述します. ------------------------------------------------------------- .. math:: \begin{array}{ll} \bf{制約条件} \\ \hline \sum_{i \in OilField}{prodX_{i,j} \cdot x_i} \ge norma_j, \quad \forall j \in Product & 製品jのノルマ/週の制約式 \\ \hline \\ \bf{定数} \\ \hline prodX_{i,j}, \quad i \in OilField, j \in Product & 油田iの製品j生産量/日 \\ \hline norma_j, \quad j \in Product & 製品jのノルマ/週 \\ \hline \end{array} ------------------------------------------------------------- 対応する PySIMPLE の記述は,以下のようになります.:: # 油田 i の製品 j 生産量/日 prodXvalue = {(0,'重油'): 6, (0,'ガス'): 4, (1,'重油'): 1, (1,'ガス'): 6} prodX = Parameter(index=(i,j), value=prodXvalue, name='油田の生産量') # 製品ノルマ problem += Sum(prodX[i,j]*x[i], i) >= norma[j], '製品ノルマ' 複数の添字に依存する定数を宣言する際には,``index=(i,j,..)`` と指定します. 複数の添字に対する値は辞書のキーをタプルにします. ``Sum()`` は指定した添字 i のみの和をとります. i, j について和をとる場合は,``Sum(任意の式, (i,j))`` と記述します. 実行結果は以前と同様になります. ここまでの変更をまとめて,添字,変数,定数,制約条件,目的関数を分類し整理すると, 定式化と PySIMPLE の記述は次のようになります. ------------------------------------------------------------- .. math:: \begin{array}{ll} \bf{添字} \\ \hline i \in OilField = \{ 0, 1 \} & 油田を表す添字 \\ \hline j \in Product = \{ 重油, ガス \} & 製品を表す添字 \\ \hline \\ \bf{定数} \\ \hline costX_i, \quad i \in OilField & 油田iの運転コスト/日 \\ \hline norma_j, \quad j \in Product & 製品jのノルマ/週 \\ \hline prodX_{i,j}, \quad i \in OilField, j \in Product & 油田iの製品j生産量/日 \\ \hline \\ \bf{変数} \\ \hline x_i, \quad i \in OilField & 油田iの運転日数/週 \\ \hline \\ \bf{目的関数(最小化)} \\ \hline \sum_{i \in OilField}{costX_i \cdot x_i} & 運転コスト/週 \\ \hline \\ \bf{制約条件} \\ \hline \sum_{i \in OilField}{prodX_{i,j} \cdot x_i} \ge norma_j & 製品jのノルマ/週の制約式 \\ \hline 0 \le x_i \le 5, \forall i \in OilField & 油田iの週あたりの運転日数制約 \\ \hline \end{array} ------------------------------------------------------------- :: from pysimple import Problem, Element, Parameter, Variable, Sum problem = Problem(name='油田問題4') # 油田を表す添字 i = Element(value=[0, 1], name='油田') # 製品を表す添字 j = Element(value=['重油', 'ガス'], name='製品') # 油田 i の運転コスト/日 costX = Parameter(index=i, value={0: 180, 1: 160}, name='油田運転コスト') # 製品 j のノルマ/週 norma = Parameter(index=j, value={'重油': 12, 'ガス': 24}, name='製品ノルマ') # 油田 i の製品 j 生産量/日 prodXvalue = {(0,'重油'): 6, (0,'ガス'): 4, (1,'重油'): 1, (1,'ガス'): 6} prodX = Parameter(index=(i,j), value=prodXvalue, name='油田の生産量') # 油田 i の運転日数(変数) x = Variable(lb=0, ub=5, index=i, name='油田の運転日数') print(costX) print(norma) print(prodX) # 運転コスト/週(目的関数) problem += Sum(costX[i]*x[i], i), '全運転コスト' # 製品ノルマ problem += Sum(prodX[i,j]*x[i], i) >= norma[j], '製品ノルマ' # 求解 print(problem) problem.solve() # 結果出力 print(x.val) print(problem.objective.val) このモデルは PySIMPLE のサンプルとして同梱されています. このサンプルを実行するには次のようにします.:: $ python -m pysimple.sample.tutorial oil4