制約最適化モジュール SCOP   東京海洋大学 久保幹雄.

Slides:



Advertisements
Similar presentations
Absolute Orientation. Absolute Orientation の問題 二つの座標系の間における剛体 (rigid body) 変換を復元す る問題である。 例えば: 2 台のステレオカメラから得られた3次元情報の間の関 係を推定する問題。 2 台のステレオカメラから得られた3次元情報の間の関.
Advertisements

情報基盤アルゴリズムとして のメタヒューリスティクスの 研究 茨木俊秀、巳波弘佳、藤原洋志、 千葉英史、関口良行(関西学院大 学)、 藤重悟(京都大学)、 柳浦睦憲(名古屋大学)、 野々部宏司(法政大学)、 梅谷俊治(電気通信大学)
表計算ソフトウェア 関数の利用(基本編) Excel. 関数とは 関数とは ・ 計算方法があらかじめ定義され た 数式のこと ・ 必要な値を定められた書式に 従っ て入力するだけで、簡単に計算結 果を求めることができる.
2008/09/19 ~ 2008/09/20 スケジューリング・シンポジウム 2008 スタッフスケジューリングにおける 修正 しやすい解を知る為の実験とその考 察 ○ 総合研究大学院大学 久保琢磨 国立情報学研究所 (NII) 宇野毅明.
木探索によるCSPの解法 (Tree search algorithms for solving CSPs) 認知システム論 制約充足( 2 ) 制約をみたす組合せを探すエージェント バックトラック法 フォワードチェック 動的変数順序.
プログラミング言語論 第10回(演習) 情報工学科 木村昌臣   篠埜 功.
到着時刻と燃料消費量を同時に最適化する船速・航路計画
ネットワーク理論講義補助資料 Text. 組合せ最適化とアルゴリズム 4.5 節 主・双対法 pp
近似アルゴリズム 第10章 終了時刻最小化スケジューリング
ある最適化問題 スポーツスケジューリング スポーツスケジューリングとは? 生成方法 プログラムと問題点 2001年2月7日(水)
Pattern Recognition and Machine Learning 1.5 決定理論
班紹介 描画班一同.
第三回 線形計画法の解法(1) 標準最大値問題 山梨大学.
最短路問題をGurobiで解こう! 流通最適化工学 補助資料.
実行時のメモリ構造(1) Jasminの基礎とフレーム内動作
Lightweight Language Weekend ls-lRシェル
第四回 線形計画法(2) 混合最大値問題 山梨大学.
最適化ソルバーのための Python言語入門
C言語 配列 2016年 吉田研究室.
Object Group ANalizer Graduate School of Information Science and Technology, Osaka University OGAN visualizes representative interactions between a pair.
土木計画学 第11回(12月21日) 土木計画と説明責任 計画における代替案の作成1 担当:榊原 弘之.
1章前半.
湘南工科大学 2013年12月10日 プログラミング基礎1 湘南工科大学情報工学科 准教授 小林 学.
~ 日本の製造業を応援する無料の本格的スケジューラ ~
ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31.
シミュレーション演習 G. 総合演習 (Mathematica演習) システム創成情報工学科
ネットワーク理論講義補助資料 Text. 組合せ最適化とアルゴリズム 4.3 節 Lagrange緩和 pp
二分探索木によるサーチ.
第7回 条件による繰り返し.
情報工学総合演習 D-I 近似アルゴリズム 埼玉大学 理工学研究科 山田 敏規、 橋口 博樹、 堀山 貴史
Linear Relaxation for Hub Network Design Problems
経営システム工学入門実験 ロジスティクス 第3回
割当て問題 • 割当問題の記法・定式化 • 拡張 • 特殊ケース(マッチング) • 3種類のものを割当てる問題.
ORの手法(組合せ最適化) 社会情報特講Ⅲ 大堀隆文(非常勤講師).
PROGRAMMING IN HASKELL
情報工学Ⅱ (第9回) 月曜4限 担当:北川 晃.
ネットワーク上での社会的効用と個人的効用の対立問題に対するアルゴリズム的研究
第10回関数 Ⅱ (ローカル変数とスコープ).
AMPLについて 2011年12月2日(金) 経営システム工学科 森戸 晋.
混合ガウスモデルによる回帰分析および 逆解析 Gaussian Mixture Regression GMR
第14章 モデルの結合 修士2年 山川佳洋.
第7回 条件による繰り返し.
第7章 疎な解を持つカーネルマシン 修士2年 山川佳洋.
情報基礎Ⅱ (第11回) 月曜4限 担当:北川 晃.
スケジューリング最適化システム OptSeq II Pythonモジュールの使い方 補助資料:OptSeq II によるスケジューリング入門 トライアルバージョン
連続領域におけるファジィ制約充足問題の 反復改善アルゴリズムによる解法 Solving by heuristic repair Algorithm of the Fuzzy Constraint Satisfaction Problems with Continuous Domains 北海道大学.
ファジィ制約充足問題への 連続領域の導入 Introducing continuous domains to
第4回 線形計画 2000年11月 第4回 線形計画.
第5章 計算とプログラム 本章で説明すること ・計算の概観と記述法 ・代表的な計算モデル ・プログラムとプログラム言語.
ナップサック問題 クマさん人形をめぐる熱いドラマの結末.
統計ソフトウエアRの基礎.
サポートベクターマシン Support Vector Machine SVM
Selfish Routing 4章前半 岡本 和也.
サプライ・チェイン最適化における モデリングについて
情報工学Ⅱ (第9回) 月曜4限 担当:北川 晃.
Solver for COnstraint Programming:スコープ Pythonモジュールの使い方
土木計画学 第12回(1月14日) 計画における代替案の作成2 担当:榊原 弘之.
経営システム工学入門実験 ロジスティクス 第3回
論理回路 第5回
半正定値計画問題(SDP)の 工学的応用について
精密工学科プログラミング基礎 第7回資料 (11/27実施)
コストのついたグラフの探索 分枝限定法 A*アルゴリズム.
情報工学Ⅱ (第8回) 月曜4限 担当:北川 晃.
Cプログラミング演習 ニュートン法による方程式の求解.
コンパイラ 2012年10月11日
精密工学科プログラミング基礎Ⅱ 第2回資料 今回の授業で習得してほしいこと: 配列の使い方 (今回は1次元,次回は2次元をやります.)
関数と再帰 教科書13章 電子1(木曜クラス) 2005/06/22(Thu.).
オブジェクト指向言語における セキュリティ解析アルゴリズムの提案と実現
第10回 関数と再帰.
グラフの帯域幅連続多重彩色 を求めるアルゴリズム (Bandwidth Consective Multicolorings of Graphs) 西関研究室 西川和秀.
Presentation transcript:

制約最適化モジュール SCOP   東京海洋大学 久保幹雄

目次 制約最適化ソルバーSCOPとは 制約最適化ソルバーSCOPの特徴 Pythonインターフェイス 仕事割当問題 生産割当問題 車の投入順決定問題 部屋割当問題 人員割当問題

制約最適化とは 制約最適化:数理最適化とは異なり,組合せ最適化に特化したパラダイムで,(重み付き)制約充足問題を対象 制約充足問題(constraint satisfaction problem) 与えられた制約を満たす解が存在するかを判定する問題 重み付き制約充足問題(weighted constraint satisfaction problem) 単に制約を満たす解を求めるだけでなく,制約からの逸脱量の重み付き和(ペナルティ)を最小化する問題 逸脱を許さない制約(絶対制約,ハード制約) 逸脱を許す制約(考慮制約,ソフト制約) 目的関数は,考慮制約として処理 SCOPは重み付き制約 充足問題を対象とする

大規模な制約最適化問題を高速に解くためのソルバー 制約最適化ソルバーSCOPとは 大規模な制約最適化問題を高速に解くためのソルバー 茨木先生(京都大学名誉教授)と野々部先生(法政大学)の開発したメタヒューリスティクスを基礎 トライアルバージョン (15変数まで)http://www.logopt.com/scop.htm 簡易モデリング言語(テキスト)によるモデル作成 Pythonからの呼び出し ライブラリ呼び出しによる利用が可能 (C++, Visual Basic, C# )

制約最適化ソルバーSCOPの特徴 誰でも効率の良い定式化が書ける 大規模組合せ最適化問題を解くのが得意 変数の領域を定義 制約の表現力大 混合整数最適化ソルバーと異なり定式化の強弱によらない 大規模組合せ最適化問題を解くのが得意 変数の領域を定義 変数の数が少なくできる 制約の表現力大 非凸2次制約(混合整数最適化ソルバーは凸のみ) 相異制約 考慮(ソフト)制約 実行不可能性の回避

制約最適化ソルバーSCOPモデルの構成 変数(variable): 最適化によって決めるもの.   変数は,与えられた集合(領域)から1つの要素(値)を選択. 領域(domain;ドメイン): 変数ごとに決められた変数のとりえる値の集合.   数でなくても良い  表現力が大  変数の数が少ない 制約(constraint): 幾つかの変数が同時にとることのできる値に制限を付加するための条件. 制約の重み : 正数(考慮制約を定義)         inf(無限大;絶対制約を定義) 制約の種類 : Linear (線形制約),Alldiff (相異制約), Quadratic (非凸2次制約)

scop.pyモジュールとは scop.py:制約最適化ソルバーSCOPをPythonから直接呼び出して,求解するためのモジュール  (ソース公開しているため,ユーザが書き換え可能) scop.pyモジュールの構成 モデルクラス Model 変数クラス Variable 制約クラス Constraint 線形制約クラス Linear 2次制約クラス Quadratic 相異制約クラス Alldiff

クラス間の関係と主要なメソッド・属性

scop.pyモジュールを用いての モデル作成手順 データ読み込み モデルオブジェクト生成 モデルオブジェクトに変数追加 モデルオブジェクトに制約追加 求解オプション設定 求解

仕事割当問題1 1 2 A B C 3人の作業員 A,B,C を3つの仕事 0,1,2 に割り当てる. (3人の作業員はそれぞれ異なる仕事に割り当てる必要がある.) 割当費用= 1 2 A 15 20 30 B 7 12 C 25 10 13 割当は相異制約(Alldiff),割当費用は線形制約(Linear)

定式化 仕事割当問題1 混合整数最適化の定式化: 制約最適化の場合: 上記の式(2),(3)を下記のように簡略化できる. 作業員iが仕事jに割当られるときの割当費用cijの合計を最小化 各仕事にはいずれかの 作業員を割り振る 各作業員はいずれかの 仕事に割り振られる 作業員iの仕事jへ割り振られるとき1, その他0である変数 制約最適化の場合:  上記の式(2),(3)を下記のように簡略化できる.                      各作業員を表す変数 Xi は領域Di (仕事0,1,2)から1つの値を選択. 変数の数が1/仕事数 になる

Python インターフェイスでのモデル作成1 (仕事割当問題1:assign1.py ) 無料配布例題集のファイル名 from scop import * #scop.pyモジュールを読み込む. #データ作成 workers=['A','B','C'] #作業員のデータをリストで保管. Jobs = [0,1,2]       #作業のデータをリストで保管. Cost={('A',0):15, ('A',1):20, ('A',2):30, #割当費用を辞書で保管. (‘B’,0): 7, (‘B’,1):15, (‘B’,2):12, 例えば, ('A',0):15は作業員A ('C',0):25, ('C',1):10, ('C',2):13 } が仕事0に割り当てられるとき の費用が15であることを表す. #モデル作成 m=Model()   #モデルオブジェクト(インスタンス)mを生成. 

Python インターフェイスでのモデル作成2 (仕事割当問題1:assign1.py ) 変数名 領域 予約語 モデルテキスト: variable A in { 0,1,2 } variable B in { 0,1,2 } variable C in { 0,1,2 } 作業員をいずれかの作業に割り振ることを表す変数: x={} #変数を保管するための辞書を作成. for i in workers: x[i]=m.addVariable(name=i,domain=Jobs) #モデルに変数を追加. 変数追加メソッドaddVariable(変数名,リスト形式の変数の領域) Python入力:

Python インターフェイスでのモデル作成3 (仕事割当問題1:assign1.py ) 定式化: モデルテキスト: AD: weight= inf type=alldiff B C A ; 制約名 重み:必ず守る必要のある場合,inf 制約タイプ 変数リスト Python記述: #すべての作業員が異なる作業に割り当てられることを表す相異制約に追加するための変数リストを作成. xlist=[] for i in x: xlist.append(x[i]) #すべての作業員が異なる作業に割り当てられることを表す制約. con1=Alldiff('AD',xlist,weight='inf') m.addConstraint(con1)   #作成した制約をモデルに追加する. 絶対制約 相異制約:Alldiff ('制約名',変数リスト,制約重み)

Python インターフェイスでのモデル作成4 (仕事割当問題1:assign1.py ) 定式化: 重み:目的関数など考慮制約の場合,1など整数 制約名 制約タイプ モデルテキスト: linear_constraint: weight= 1 type=linear 15(A,0) 20(A,1) 30(A,2) 7(B,0) 15(B,1) 12(B,2) 25(C,0) 10(C,1) 13(C,2) <=0 sum [費用(変数,値)]<=0:例えば,15(A,0)は,作業員Aが仕事0に割り振られるときの費用が15であることを表す. Python記述: #作業員の各作業への割当費用を表す制約. con2=Linear('linear_constraint',weight=1,rhs=0,direction='<=') for i in workers: for j in Jobs: con2.addTerms(Cost[i,j],x[i],j)  m.addConstraint(con2)    #作成した制約をモデルに追加する. 絶対制約 線形制約: Linear('制約名', 制約重み,右辺値,制約向き) 左辺追加メソッドaddTerms(係数,変数,値)

Python インターフェイスでのモデル作成5 (仕事割当問題1:assign1.py ) print (m)             #モデルをプリントする. 出力結果: Model: number of variables = 3 number of constraints= 2 variable A:['0', '1', '2'] = None variable B:['0', '1', '2'] = None variable C:['0', '1', '2'] = None AD: weight= inf type=alldiff B C A ; :LHS =0 linear_constraint: weight= 1 type=linear 15(A,0) 20(A,1) 30(A,2) 7(B,0) 15(B,1) 12(B,2) 25(C,0) 10(C,1) 13(C,2) <=0 :LHS =0

Python インターフェイスでのモデル作成6 (仕事割当問題1:assign1.py ) m.Params.TimeLimit=1   #求解時間を1秒に設定する. sol,violated=m.optimize()  #解と違反制約をsolとviolatedへ保存. print ('solution‘) for x in sol:              #結果のプリント print (x,sol[x]) print ('violated constraint(s)') for v in violated:           #違反制約のプリント print (v,violated[v]) 出力結果: solution C 1 A 0 B 2 violated constraint(s) linear_constraint 37       

Python インターフェイスでのモデル作成7 (仕事割当問題1:assign1.py ) 求解後自動的に出力される結果ファイルscop_out.txtの一部: [best solution] A:0 C:1       #作業員Aが作業0,作業員Cが作業1, B:2        作業員Bが作業2に割り振られたことを表す. penalty: 0/37 (hard/soft)  #hardは重みinfの絶対制約,                   softは正数重みの考慮制約の逸脱値 [Violated constraints] obj: 37    #割当費用が37であることを表す. 1 2 A 15 20 30 B 7 12 C 25 10 13 割当費用:37 =15+12+10

仕事割当問題2 5人の作業員 A,B,C,D,E を3つの仕事 0,1,2 に割当 各仕事の必要人数は(1,2,2)人 作業員AとCは仲が悪いので,異なる仕事に割り振る 割当費用= 1 2 A 15 20 30 B 7 12 C 25 10 13 D 18 3 E 5 17

定式化 仕事割当問題2 混合整数最適化定式化: 制約最適化の場合: 作業員iが仕事jに割当られるときの割当費用cijの合計を最小化 各仕事に割り振られる作業員の数   ≧ 作業の必要人数下限 作業員AとCを同じ仕事に 割り振ることができない 各作業員をいずれかの 仕事に割り振る 作業員iの仕事jへ割り振られるとき1, その他0である変数 制約最適化の場合:

Python インターフェイスでのモデル作成1 (仕事割当問題2 :assign3.py) from scop import * m=Model()                #モデル作成 workers=['A','B','C','D','E']      #作業員のデータをリストで保管. Jobs = [0,1,2]          #作業のデータをリストで保管. Cost={ ('A',0):15, ('A',1):20, ('A',2):30, ('B',0): 7, ('B',1):15, ('B',2):12, ('C',0):25, ('C',1):10, ('C',2):13,  #割当費用を辞書で保管. ('D',0):15, ('D',1):18, ('D',2): 3, ('E',0): 5, ('E',1):12, ('E',2):17 } LB={0: 1, 1: 2, #各作業の必要人数下限 2: 2}

Python インターフェイスでのモデル作成2 (仕事割当問題2 :assign3.py) 定式化 モデルテキスト variable A in { 0,1,2 } variable B in { 0,1,2 } variable C in { 0,1,2 } variable D in { 0,1,2 } variable E in { 0,1,2 } Python入力 #作業を領域とする作業員変数作成. x={} for i in workers:               x[i]= m.addVariable(i,Jobs) 重み1,右辺0の考慮制約 定式化 モデルテキスト obj: weight= 1 type=linear 15(A,0) 20(A,1) 30(A,2) 7(B,0) 15(B,1) 12(B,2) 25(C,0) 10(C,1) 13(C,2) 15(D,0) 18(D,1) 3(D,2) 5(E,0) 12(E,1) 17(E,2) <=0 Python入力 #作業員の各作業への割当費用を表す制約. obj=Linear('obj',1,0,'<=') for i in workers: for j in Jobs: obj.addTerms(Cost[i,j],x[i],j) m.addConstraint(obj)

Python インターフェイスでのモデル作成3 (仕事割当問題2 :assign3.py) 定式化 モデルテキスト LB0: weight= inf type=linear 1(A,0) 1(B,0) 1(C,0) 1(D,0) 1(E,0) >=1 LB1: weight= inf type=linear 1(A,1) 1(B,1) 1(C,1) 1(D,1) 1(E,1) >=2 LB2: weight= inf type=linear 1(A,2) 1(B,2) 1(C,2) 1(D,2) 1(E,2) >=2 Python入力 #各仕事に割り振られる作業員の数≦ 作業の必要人数下限 LBC={} for j in Jobs: LBC[j]=Linear( 'LB{0}'.format(j),'inf',LB[j],'>=') for i in workers: LBC[j].addTerms(1,x[i],j) m.addConstraint(LBC[j]) 右辺がLB[j]の絶対制約

Python インターフェイスでのモデル作成4 (仕事割当問題2 :assign3.py) 定式化 モデルテキスト conflict: weight=100 type=quadratic 1(A,0)(C,0) 1(A,1)(C,1) 1(A,2)(C,2) =0 sum [費用(変数1,値1) (変数2,値2)]=0:例えば, 1(A,0)(C,0)は,AとCが仕事0に割り振られるときの費用が1であることを表す. 重み:目的関数など考慮制約の場合,1など整数 制約名 制約タイプ 重み100,右辺0 の考慮制約 Python入力 #作業員AとCを同じ仕事に割り振ることができない conf=Quadratic('conflict',100,0,'=') for j in Jobs: conf.addTerms(1,x['A'],j,x['C'],j) m.addConstraint(conf) 2次制約: Quadratic ('制約名', 制約重み,右辺値,制約向き) 左辺追加メソッドaddTerms (係数1,変数1,係数2,変数2,領域値)

Python インターフェイスでのモデル作成5 (仕事割当問題2 :assign3.py) m.Params.TimeLimit=1   #求解時間を1秒に設定する. sol,violated=m.optimize()  #解と違反制約をsolとviolatedへ保存. 求解後自動的に出力される結果ファイルscop_out.txtの一部: [best solution] A: 0 B: 2 C: 1 D: 2 E: 1 penalty: 0/52 (hard/soft) [Violated constraints] obj: 52    割当費用:52=15+12+10+3+12 1 2 A 15 20 30 B 7 12 C 25 10 13 D 18 3 E 5 17

どのような生産スケジュールを作成すれば生産段取り費用を最小化できるか 生産割当(スケジュール)問題 在庫量 a a b b b … 5 生産ライン 段取費用: a→b:10  b→a:30 期 ・ 同じ生産ラインで2種類の製品aとbを生産. ・ 1期(1日)に1種類の製品のみ生産可能. ・ 製品の切り替えには順序依存の段取費用が必要.    (a→bの段取費用とb→aの段取費用が異なる) ・ 計画期間5期. ・ 需要量は期によって変動. ・ 在庫量には上下限制約がある. どのような生産スケジュールを作成すれば生産段取り費用を最小化できるか ?

車の投入順決定問題 上記の制約の下でどの順序で車を生産ラインに投入すれば良いか. 6種類の車(A,B,C,D,E,F)を同じ生産ラインで組み立てる. 需要量(D): A:1台,B :1台,C :2台,D :2台,E :2台,F :2台 各Optionを付ける必要のある車の種類とOptionの処理能力は下記の通り. Option 車の種類 処理能力 Capacity/Length A E F 1/2 1 C D F 2/3 2 A E 1/3 3 A B D 2/5 4 C 1/5 e.g.:処理能力=2/3は,連続する3つの作業 スペースで2つしか処理できないことを表す. line A? C? ・・・ ・・・ ・・・ ・・・ ・・・ ・・・ ・・・ E? 上記の制約の下でどの順序で車を生産ラインに投入すれば良いか.

定式化 車の投入順決定問題 混合整数最適化定式化: 制約最適化の場合: 各種類の車の生産量は需要量と同じ 各Optionの作業効率制約 各順番jにはいずれかの 種類の車を割り当てる 種類iの車をj番目に投入するときに1, その他のとき0であることを表す変数 制約最適化の場合:

Python インターフェイスでのモデル作成1 (車投入順序決定問題 :car_small.py ) データ作成 from scop import * m=Model() Type=['A','B','C','D','E','F'] #車の種類 Number={'A':1,'B':1,'C':2,'D':2,'E':2,'F':2} #車の種類ごとの需要量 n=sum(Number[i] for i in Number) #車の全体の生産必要な台数 Option=[['A','E','F'], # Optionごとの車の種類 ['C','D','F'], ['A','E'], ['A','B','D'], ['C']] Length=[2,3,3,5,5]          # Optionごとの処理能力:Capacity/Length Capacity=[1,2,1,2,1]              

Python インターフェイスでのモデル作成2 (車投入順序決定問題 :car_small.py ) 定式化 モデルテキスト variable seq[0] in { A,B,C,D,E,F } variable seq[1] in { A,B,C,D,E,F } … variable seq[9] in { A,B,C,D,E,F } Python入力 #何番目にどの種類の車を投入するかを表す変数. X={} for j in range(n): X[j]=m.addVariable('seq[{0}] '.format(j),Type)

Python インターフェイスでのモデル作成3 (車投入順序決定問題 :car_small.py ) 定式化 モデルテキスト req[A]: weight= 1 type=linear 1(seq[0],A) 1(seq[1],A) 1(seq[2],A) 1(seq[3],A) 1(seq[4],A) 1(seq[5],A) 1(seq[6],A) 1(seq[7],A) 1(seq[8],A) 1(seq[9],A) =1 … req[F]: … Python入力 for i in Type: #各種類の車の生産量制約 L1=Linear( 'req[{0}] '.format(i),direction='=',rhs=Number[i]) for j in range(n): L1.addTerms(1,X[j],i) m.addConstraint(L1)

Python インターフェイスでのモデル作成4 (車投入順序決定問題 :car_small.py ) 定式化 モデルテキスト ub[0_1]: weight= 1 type=linear 1(seq[1],A) 1(seq[1],E) 1(seq[1],F) 1(seq[2],A) 1(seq[2],E) 1(seq[2],F) <=1 … Option0の処理能力が1/2であるため, Option0を付ける必要のある車(A,E,F)を1番目と2番目に連続投入することができないことを表す. Python入力 for i in range(len(Length)): #各Optionの処理能力の制約 for k in range(n-Length[i]+1): L2=Linear('ub[{0}_{1}] '.format(i,k),direction='<=',rhs=Capacity[i]) for t in range(k,k+Length[i]): for j in range(len(Option[i])): L2.addTerms(1,X[t],Option[i][j]) m.addConstraint(L2)

車の投入順決定問題(結果) A C F B F D E C D E 順番: 0 1 2 3 4 5 6 7 8 9 line 処理能力 順番:  0 1 2 3 4 5 6 7 8 9 line A C F B F D E C D E 処理能力 Option 1/2 2/3 1 1/3 2 2/5 3 1/5 4 e.g.: A種類の車にはOption0,2,3を付ける. C種類の車にはOption1,4を付ける. e.g.: Option1処理能力は2/3であるため, 連続する3つの作業スペース中で高々2つを処理.

? 部屋割当問題 各人をどの部屋に割り当てるか ・ 学生寮に学生を割り振る.(400人を100部屋に割り振る.) ・ 学生寮に学生を割り振る.(400人を100部屋に割り振る.) ・ 1部屋には4人入居可能. ・ 入居中の学生は移動させたくない. ・ 各部屋に割り振り可能な留学生人数には上限がある. ・ 相性の悪い学生の同じ部屋への割り振りを避けたい.

定式化 部屋割当問題 混合整数最適化定式化: 学生i,j間の相性をDijで表す. (Dijの値が大きいほど相性が悪い) 同じ部屋に割り振られることを変数の掛け算で表す 各部屋に割り振られる学生人数制約 各部屋に割り振られる留学生人数制約 制約最適化の定式化:                      学生iの割当可能な部屋の集合Drを領域とする変数.        学生iが部屋rに入居中の場合,ドメインを入居中の部屋{r}に設定.

Python インターフェイスでのモデル作成1 (部屋割当問題 ) 変数: x={} #学生iが部屋rに入居中の学生の場合,学生iの領域は入居中の部屋r. for i in FixStudent: for r in Room: if Fix[r][i] ==1: x[i] = m.addVariable('x[{0}]'.format(i),[r]) #学生iがどの部屋にも入居中でない場合,学生iの領域は割当可能なすべての部屋. for i in FreeStudent: x[i] = m.addVariable('x [{0}]'.format(i),Room)

Python インターフェイスでのモデル作成2 (部屋割当問題 ) 目的関数: obj=Quadratic('obj',weight=1,rhs=0,direction='<=') for i in FreeStudent: for j in FreeStudent: if i >= j: continue for r in Room: obj.addTerms(D[i][j],x[i],r,x[j],r) for i in FixStudent: if Fix[r][i]==1: #学生i,jが自由に割当可能な場合, 学生i,jが同じ部屋rに割り振られる場合の相性を表すDijの和を最小化 #学生iが部屋rに入居中で,学生jが自由に割当可能な場合,学生 i,jが同じ部屋rに割り振られる場合の相性を表すDijの和を最小化

Python インターフェイスでのモデル作成3 (部屋割当問題 ) 制約: #各部屋に割り振られる人数は部屋の容量以下 UB={} for r in Room: UB[r]=Linear('UB{0}'.format(r), weight='inf',rhs=Size[r][1],direction='<=') for i in FixStudent: if Fix[r][i]==1: UB[r].addTerms(1,x[i],r) for i in FreeStudent: m.addConstraint(UB[r])

Python インターフェイスでのモデル作成4 (部屋割当問題 ) 制約: #各部屋の留学生の人数は部屋ごとの留学生上限以下であることを表す制約 ForeignUB ={} for r in Room: ForeignUB[r]=Linear('ForeignUB{0}'.format(r), weight='inf',rhs=2,direction='<=') for i in FixStudent: if Fix[r][i]==1 and Foreign[i]==1: ForeignUB[r].addTerms(1,x[i],r) for i in FreeStudent: if Foreign[i]==1: m.addConstraint(ForeignUB[r])

? 人員割当問題 朝 昼 夜 休 ・ 各スタッフは1日高々1つのシフトしか行うことができない. 計画期間 出勤日数min 出勤日数max ? 3人のスタッフ 各シフトの必要人数 シフトの種類 朝 昼 夜 休 ・ 各スタッフは1日高々1つのシフトしか行うことができない. ・ 異なるシフトに移るときには,必ず休日を入れる. ・ シフト「昼」,「夜」は,最低2日間は連続で行う. ・ シフト「夜」は4日以上連続で行うことができない.

Python インターフェイスでのモデル作成1 (人員割当問題 :staff2.py ) #データ設定 periods=[1,2,3,4,5,6,7]         shifts=[0,1,2,3]              staffs=["A","B","C","D"]       var={} for i in staffs: for t in periods: var[i,t]=m.addVariable(name=i+str(t),domain=shifts) #期 #シフト #スタッフ #期tのスタッフiを変数,シフトの集合をドメインに設定 数理最適化定式化での変数:   x its ∊ 0,1 ∀ i,t,s SCOPの定式化の変数:        var[i,t]  ∊ {シフトsの集合}

Python インターフェイスでのモデル作成2 (人員割当問題 :staff2.py ) #各スタッフは最低3日以上出勤する必要がある.(「休」を除き,各スタッフに割り当てられるシフトの合計が3以上である制約) LB={} for i in staffs: LB[i]=Linear("LB_{0}".format(i),rhs=3,direction=">=")   for t in periods: for s in range(1,len(shifts)): LB[i].addTerms(1,var[i,t],shifts[s]) m.addConstraint(LB[i]) #各スタッフは1日以上休みを取る必要がある. (「休」を除き,各スタッフに割り当てられるシフトの合計が6以下である制約) UB={} UB[i]=Linear("UB_{0}".format(i),rhs=6,direction="<=") for t in periods: UB[i].addTerms(1,var[i,t],shifts[s]) m.addConstraint(UB[i]) t,s x its ≧3     ∀ i t,s x its ≦6     ∀ i

Python インターフェイスでのモデル作成2 (人員割当問題 :staff2.py ) #各スタッフの夜勤回数は最大4回まで可能. UB_night={} for i in staffs: UB_night[i]=Linear("UB_night_{0}".format(i),rhs=4,direction="<=") for t in periods: UB_night[i].addTerms(1,var[i,t],shifts[-1]) m.addConstraint(UB_night[i]) #各シフトには1人のスタッフを割り当てる必要がある. UB_shift={} for s in range(1,len(shifts)): UB_shift[t,s]=Linear(“UBshift_{0}_{1}”.format(t,s),rhs=1,direction=“=”)              for i in staffs: UB_shift[t,s].addTerms(1,var[i,t],shifts[s]) m.addConstraint(UB_shift[t,s]) t,s=3 x its ≦4     ∀ i i x its =1     ∀t,s

Python インターフェイスでのモデル作成2 (人員割当問題 :staff2.py ) #異なるシフトに移る場合は休みを入れる必要がある.(異なるシフトが2日間連続で行うのを禁止する制約.) Forbid={} for i in staffs: for t in periods: for s in range(1,len(shifts)): Forbid[(i,t,s)]=Linear("Forbid_{0}_{1}_{2}".format(i,t,s),rhs=1) Forbid[(i,t,s)].addTerms(1,var[i,t],shifts[s]) for k in range(1,len(shifts)): if k!=s: if t==periods[-1]: Forbid[(i,t,s)].addTerms(1,var[i,1],shifts[k]) else: Forbid[(i,t,s)].addTerms(1,var[i,t+1],shifts[k]) m.addConstraint(Forbid[(i,t,s)]) x its + k≠s x i,t+1,k ≦1 ∀ i,t,s

Python インターフェイスでのモデル作成2 (人員割当問題 :staff2.py ) #シフト「昼」,「夜」は,最低2日間は連続で行う. Cons={} for i in staffs: for t in periods: for s in range(2,len(shifts)): Cons[(i,t)]=Linear("Cons_{0}_{1}".format(i,t),direction=">=") Cons[(i,t)].addTerms(-1,var[i,t],shifts[s]) if t==1: Cons[(i,t)].addTerms(1,var[i,periods[-1]],shifts[s]) else: Cons[(i,t)].addTerms(1,var[i,t-1],shifts[s]) if t==periods[-1]: Cons[(i,t)].addTerms(1,var[i,1],shifts[s]) Cons[(i,t)].addTerms(1,var[i,t+1],shifts[s]) m.addConstraint(Cons[(i,t)]) −x its + x i,t−1,s + x i,t+1,s ≧0 ∀ i,t,s∈{2,3}

人員割当問題結果 出勤日数min 出勤日数max