1 / 82

スケジューリングモデルとは

スケジューリング最適化システム OptSeq II Python モジュールの使い方 補助資料: OptSeq II によるスケジューリング入門 トライアルバージョン http://www.logopt.com/OptSeq/OptSeq.htm. スケジューリングモデルとは. 作業( activity ;活動) :遂行すべき仕事のこと.別名,オペレーション( operation ),ジョブ,仕事 (job) ,タスク (task) .作業時間や納期の情報が付加される.

Download Presentation

スケジューリングモデルとは

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. スケジューリング最適化システムOptSeq IIPythonモジュールの使い方補助資料:OptSeq II によるスケジューリング入門 トライアルバージョンhttp://www.logopt.com/OptSeq/OptSeq.htm

  2. スケジューリングモデルとは 作業(activity;活動):遂行すべき仕事のこと.別名,オペレーション(operation),ジョブ,仕事(job),タスク(task).作業時間や納期の情報が付加される. 先行(時間)制約(precedence (time) constraint):ある作業(ジョブ,活動)がある作業(ジョブ,活動)の前に処理されなければならないことを表す制約. 資源(resource):作業を行うときに必要とされるもので,その量に限りがあるもの.機械(machine)はジョブによって占有される資源.その他,人員,材料,お金なども全部資源.

  3. optseq2.pyモジュールとは • スケジューリングソルバーOptSeqを,超高級言語Pythonから直接呼び出して,求解するためのモジュール • すべてPythonで書かれたクラスで構成 • ソースコード(すべてPythonで記述)も公開されているので,ユーザが書き換え可能

  4. Pythonモジュールのクラス • 作業クラス ー Activity • モードクラス ー Mode • 資源クラス ー Resource • 先行制約クラス ー Temporal • モデルクラス ー Model • パラメータクラス ー Parameters

  5. 作業クラス ー Activity 作業の定義を行う • activityの引数と引数のデフォルト値 activity(name=‘’, dudate=‘inf’, weight=1) • name : 作業の名前,文字列で入力 • dudate : 作業の納期,非負の整数または‘inf’で入力 • weight : 作業が納期遅れした時のペナルティ,positive 整数 • activityのaddModesメソッド activity.addModes(modes) • modes: モードクラスで作成 • 作業にモード(一つまたは複数のモード)を追加する時に使用 • 例: activity.addModes(mode1,mode2)

  6. モードクラス ー Mode(1) モードの定義を行う • modeの引数と引数のデフォルト値 mode(name=‘ ’, duration=0) • name: モードの名前,文字列で入力 • duration: このモードを選択した場合の作業時間 • modeのメソッド (次のページで詳しく) • addBreak(start=0, finish=0, maxtime=‘inf’)休憩に関する情報をモードに追加 • addParallel(start=1, finish=1, maxparallel=‘inf’)並列処理に関する情報をモードに追加 • addResource(resource, requirement={}, rtype=None)資源に関する情報をモードに追加

  7. モードクラス ー Mode(2) モードメソッド(1) • addBreak メソッド addBreak(start=0, finish=0, maxtime=‘inf’) • start,finish: 休憩開始時間,休憩終了時間 • maxtime: 最大休憩可能時間 • addParallel メソッド addParallel(start=1, finish=1, maxparallel=‘inf’) • start,finish: 並列開始小作業番号,並列終了小作業番号 • maxparallel: 最大並列数

  8. 作業の途中中断 •  Pythonインターフェイスによる記述 モード名.addBreak(中断開始時刻,中断終了時刻,最大中断時間) 作業Aが,0から3の区間でそれぞれ最大1中断可能: モード名.addBreak(0,3,1) 開始から2時刻で中断した例

  9. 作業の並列処理 •  Pythonインターフェイスによる記述 モード名.addParallel(開始小作業番号,終了小作業番号,最大並列数) 作業1(作業時間は3秒)を最大3単位並列可能: モード名.addParallel(1,1,3) 作業1 小作業1,小作業1

  10. 並列処理の結果 •  1番目の小作業を3単位並列可能: 1 2 3

  11. モードクラス ー Mode(3) モードメソッド(2) • addResource メソッド addResource(resource, requirement={}, rtype=None) • resource: 資源オブジェクト • requirement: 資源必要量 資源を必要とする開始時刻と終了時刻を辞書で表す.必要量を正数値として入力すると,開始0,終了 “inf”になる. 例: mode.addResource(worker,{(0,10):1}) 時刻0から時刻10までworkerという資源を1単位必要 • rtype: リソースのタイプ ----- break と max がある 例: mode.addResource(machine,{(0,"inf"):1},"break") break は休憩中も資源を1単位使用 例: mode.addResource(machine,{(0,"inf"):1},"max") max は並列処理を行う時も資源は1単位使用

  12. 資源クラス ー Resource(1) 資源の定義を行う • resourceの引数と引数のデフォルト値 resource (name=' ', capacity={}, rhs=0, direction='<=') • name : 資源の名前,文字列で入力 • capacity : 再生可能資源の最大容量; 区間と容量の辞書で入力       正数値を入力すると,開始時刻0,終了時刻 “inf”に変換  • rhs : 再生不能資源の制約 • direction : 再生不能資源制約の向き"<=" or ">=" • resourceのメソッド (次のページで詳しく) • addCapacity(start=0, finish=0, amount=1)資源に容量を追加 • addTerms(coeffs=[], vars=[], values=[])再生不能資源に関する制約の左辺追加 • printConstraint( )再生不能資源に関する制約を展開 • setRhs(rhs=0) • 再生不能資源に関する制約の右辺追加

  13. 資源クラス ー Resource(2) 資源メソッド resourceのメソッド • addCapacity(start=0, finish=0, amount=1)start, finish : 資源使用開始と終了時刻 amount : 資源の使用量 例: manpower.addCapacity(0,5,2) 時刻0から時刻5の間に資源 (manpower) を2単位使用 • addTerms(coeffs=[], vars=[], values=[]) coeffs :  追加する項; リストで入力可 vars : 作業オブジェクト; リストで入力可 values : モードオブジェクト; リストで入力可 例: budget.addTerms(1,act,express) act と言う作業が express と言うモードで行う時再生不能資源を1単位追加

  14. 時間制約クラス ー Temporal 時間制約の定義を行う • Temporal の引数と引数のデフォルト値 Temporal(pred, succ, tempType, delay) • pred : 先行作業のオブジェクト • succ : 後続作業のオブジェクト • tempType : 時間制約のタイプ; 規定値= "CS" • "CS"=Completion-Start, "SS"=Start-Start, "SC"= Start-Completion, "CC"=Completion-Completion • 先行作業の終了 (開始)時刻+delay <= 後続作業の開始 (終了) 時刻 • delay : 先行作業と後続作業の時間ずれ; 負の数も可

  15. 時間制約 時間制約オブジェクトの生成法 Temporal (先行作業 , 後続作業 , “制約タイプ” , 時間ずれ) Completion Start A B 後続作業 先行作業 作業Aの完了後に作業Bの開始 Temporal(pred=A, succ=B, tempType=“CS”, delay=0)

  16. 制約タイプ(type) Start Start type SS A B Start Completion type SC A B Completion Completion type CC A B

  17. 時間ずれ(delay) Completion Start A B delay 10 作業Bの開始可能時間帯 10 Completion Start A B delay -10 作業Bの開始可能時間帯 10

  18. 時間制約の応用 1(同時開始) •  Pythonインターフェイスによる記述 モデル名.addTemporal(先行作業,後続作業,“制約タイプ”,時間ずれ) モデル名.addTemporal(A,B,"SS",0) モデル名.addTemporal(B,A,"SS",0) AとBの同時開始 Aの開始+0 ≦ Bの開始 Aの開始=Bの開始 Bの開始+0 ≦ Aの開始

  19. 時間制約の応用 2(開始時間固定) モデル名.addTemporal(source,A,"SS",50) モデル名.addTemporal(A, source,"SS",-50) Aの開始を50に 固定 ダミーの始点(source)の開始+50 ≦ Aの開始 Aの開始-50 ≦ダミーの始点(source)の開始 sourceの開始時刻は0 Aの開始=50

  20. 時間制約の応用 3(最大・最小段取り時間) Aの完了後最小 10分最大30分で Bを開始 モデル名.addTemporal(A,B,"CS",10) モデル名.addTemporal(B,A,"SC",-30) Aの終了+10 ≦ Bの開始 Bの開始≦ Aの終了+30 Bの開始-30 ≦Aの終了 Bの開始はAの終了+[10,30]

  21. モデルクラス ー Model モデルを作成 • モデルクラスのメソッド   • addActivity(name=‘’, duedate=‘inf’, weight=1)モデルに作業を追加  (括弧内の引数説明はactivityクラス参照) • addResource(name=‘’, capacity={}, rhs=0, direction=‘<=’)モデルに資源を追加  (括弧内の引数説明はresourceクラス参照) • addTemporal(pred, succ, tempType=‘CS’, delay=0)モデルに先行制約を追加 (括弧内の引数説明はtemporalクラス参照) • optimize()モデルの最適化を行う • write(filename=‘optseq.txt’)テキスト形式のガントチャートを書く

  22. パラメータクラス ー Parameters よく使うパラメータ • TimeLimit:求解する時の制限時間;単位は秒;既定値=600秒   • OutputFlag:モデルを出力する場合True,出力しない場合False ; 既定値=False • Makespan:最大完了時刻最小化の時はTrue,それ以外の時はFalse ; 既定値=False • RandomSeed – random seedを設定;整数;既定値=1

  23. PERT: Program Evaluation and Review Technique,第二次世界大戦のポラリス潜水艦の建造で利用.(ORの古典) 航空機を早く離陸させよう! 作業1 15分 13分 27分 作業2 25分 22分 作業4 作業3 完了時刻最小化 ダミー作業 先行制約 作業5 作業1:乗客降ろし(13分) 作業2:荷物降ろし(25分) 作業3:機内清掃(15分) 作業4:乗客搭乗(27分) 作業5:荷物積み込み(22分) 点が作業(活動)のグラフ->点上活動図式

  24. 航空機を早く離陸させよう! 作業4 作業3 作業1 15分 13分 27分 ダミー作業 先行制約 作業2 作業5 ダミー作業 25分 22分 完了時刻最小化 開始時刻 終了時刻 作業1:乗客降ろし(13分) 作業2:荷物降ろし(25分) 作業3:機内清掃(15分) 作業4:乗客搭乗(27分) 作業5:荷物積み込み(22分)

  25. duration ={1:13, 2:25, 3:15, 4:27, 5:22 }       キー   値 Pythonインターフェイスによる記述(1) • OptSeqⅡのモジュールを読み込む • モデルオブジェクトm1 を作成 • 作業時間を作業をキー,作業時間を値とする辞書duration に保管 from optseq2 import *    m1=Model()         

  26. Pythonインターフェイスによる記述(2) • 作業を保管するための空の辞書actを作成 • モードを保管するための空の辞書mode を作成 act={} mode={}

  27. Pythonインターフェイスによる記述(3) • モデルオブジェクトm1 のaddActivity(“作業名”) メソッドを用いてモデルに作業を追加 • モードクラスMode(“モード名”, 作業時間) を用いてモードに必要な作業時間を入力 • addModes メソッドを用いて作業にモードを追加 for i in duration: act[i]=m1.addActivity("Act[%s]"%i) mode[i]=Mode("Mode[%s]"%i,duration[i]) act[i].addModes(mode[i])

  28. Pythonインターフェイスによる記述(4) • モデルに addTemporal (先行作業, 後続作業) メソッドを用いて時間制約を追加 m1.addTemporal(act[1],act[3]) m1.addTemporal(act[2],act[4]) m1.addTemporal(act[2],act[5]) m1.addTemporal(act[3],act[4])

  29. Pythonインターフェイスによる記述(5) • m1.optimize() を入力して求解 m1.Params.TimeLimit=1    求解時の制限時間 m1.Params.OutputFlag=True  モデルを出力する場合True    m1.Params.Makespan=True  最大完了時刻最小化の時はTrue m1.optimize()

  30. Pythonインターフェイスによる記述(6) •  Pythonコードまとめ from optseq2 import * m1=Model() duration ={1:13, 2:25, 3:15, 4:27, 5:22 } act={} mode={} for i in duration: act[i]=m1.addActivity("Act[%s]"%i) mode[i]=Mode("Mode[%s]"%i,duration[i]) act[i].addModes(mode[i]) m1.addTemporal(act[1],act[3]) m1.addTemporal(act[2],act[4]) m1.addTemporal(act[2],act[5]) m1.addTemporal(act[3],act[4]) m1.Params.TimeLimit=1 m1.Params.OutputFlag=True m1.Params.Makespan=True m1.optimize()

  31. Pythonインターフェイスによる記述(7) • 実行結果(一部) source ---: 0 0ダミーの始点の開始時刻が0 sink ---: 55 55ダミーの終点の開始時刻が55(完了時刻) activity[1] ---: 0 0--13 13作業1は0に開始されて13に終了 activity[2] ---: 0 0--25 25作業2は0に開始されて25に終了 activity[3] ---: 13 13--28 28作業3は13に開始されて28に終了 activity[4] ---: 28 28--55 55作業4は28に開始されて55に終了 activity[5] ---: 25 25--47 47作業5は25に開始されて47に終了 objective value = 55目的関数 cpu time = 0.00/1.00(s)        計算時間 iteration = 1/15962 反復回数

  32. 航空機を早く離陸させよう!最適解

  33. 航空機を早く離陸させよう! 作業4 作業3 作業1 15分 13分 27分 ダミー作業 先行制約 作業2 作業5 ダミー作業 25分 22分 完了時刻最小化 開始時刻 終了時刻 作業1:乗客降ろし(13分) 作業2:荷物降ろし(25分) 作業3:機内清掃(15分) 作業4:乗客搭乗(27分) 作業5:荷物積み込み(22分) 作業員1人

  34. Pythonインターフェイスによる記述(1) • 資源(この例題の場合は作業員)制約の記述: モデル名.addResource( “資源名”, {( 時刻1, 時刻2):供給量} ) • モードに資源使用量追加: モード名.addResource ( 資源,{(資源使用可能区間):使用量} ) r e s=m1. addResource ( "worker " , {(0 , " i n f " ) : 1} ) for i in duration: act[i]=m1.addActivity("Act[%s]"%i) mode[i]=Mode("Mode[%s]"%i,duration[i]) mode[i].addResource(res,{(0,"inf"):1}) act[i].addModes(mode[i])

  35. Pythonインターフェイスによる記述(2) •  Pythonコードまとめ m1.addTemporal(act[1],act[3]) m1.addTemporal(act[2],act[4]) m1.addTemporal(act[2],act[5]) m1.addTemporal(act[3],act[4]) m1.Params.TimeLimit=1 m1.Params.OutputFlag=True m1.Params.Makespan=True m1.optimize() from optseq2 import * m1=Model() duration ={1:13, 2:25, 3:15, 4:27, 5:22 } res=m1.addResource("worker",capacity={(0,"inf"):1}) act={} mode={} for i in duration: act[i]=m1.addActivity("Act[%s]"%i) mode[i]=Mode("Mode[%s]"%i,duration[i]) mode[i].addResource(res,{(0,"inf"):1}) act[i].addModes(mode[i])

  36. Pythonインターフェイスによる記述(3) •  実行結果(一部) source ---: 0 0 sink ---: 102 102 activity[1] ---: 47 47--60 60 activity[2] ---: 0 0--25 25 activity[3] ---: 60 60--75 75 activity[4] ---: 75 75--102 102 activity[5] ---: 25 25--47 47 objective value = 102 cpu time = 0.00/3.00(s) iteration = 0/64983

  37. 並列ショップスケジューリングピットイン時間を短縮せよ!並列ショップスケジューリングピットイン時間を短縮せよ! 3人のピットクルー (資源制約) 資源(機械)制約 があると難しい!

  38. Pythonインターフェイスによる記述(1) 3人の作業員記述:資源制約モデル名.addResource("資源名",( 時刻1, 時刻2):供給量) の供給量を3 に設定 from optseq2 import * m1=Model() duration ={1:3, 2:2, 3:2, 4:2, 5:4, 6:4, 7:4, 8:4, 9:11, 10:2 } res=m1.addResource("worker",capacity={(0,"inf"):3}) act={} mode={} for i in duration: act[i]=m1.addActivity("Act[%s]"%i) mode[i]=Mode("Mode[%s]"%i,duration[i]) mode[i].addResource(res,{(0,"inf"):1}) act[i].addModes(mode[i])

  39. Pythonインターフェイスによる記述(2) 時間制約 求解実行 m1.addTemporal(act[1],act[9]) for i in range(5,9): m1.addTemporal(act[4],act[i]) m1.addTemporal(act[i],act[10]) m1.Params.TimeLimit=1 m1.Params.OutputFlag=True m1.Params.Makespan=True m1.optimize()

  40. Pythonインターフェイスによる記述(3) •  Pythonコードまとめ m1.addTemporal(act[1],act[9]) for i in range(5,9): m1.addTemporal(act[4],act[i]) m1.addTemporal(act[i],act[10]) m1.Params.TimeLimit=1 m1.Params.OutputFlag=True m1.Params.Makespan=True m1.optimize() from optseq2 import * m1=Model() duration ={1:3, 2:2, 3:2, 4:2, 5:4, 6:4, 7:4, 8:4, 9:11, 10:2 } res=m1.addResource("worker",capacity={(0,"inf"):3}) act={} mode={} for i in duration: act[i]=m1.addActivity("Act[%s]"%i) mode[i]=Mode("Mode[%s]"%i,duration[i]) mode[i].addResource(res,{(0,"inf"):1}) act[i].addModes(mode[i])

  41. Pythonインターフェイスによる記述(4) •  実行結果(一部) source ---: 0 0 sink ---: 14 14 prepare ---: 0 0--3 3 water ---: 0 0--2 2 front ---: 0 0--2 2 jackup ---: 2 2--4 4 tire1 ---: 8 8--12 12 tire2 ---: 4 4--8 8 tire3 ---: 8 8--12 12 tire4 ---: 4 4--8 8 oil ---: 3 3--14 14 jackdown ---: 12 12--14 14 objective value = 14 cpu time = 0.00/3.00(s) iteration = 0/37644

  42. 並列ショップスケジューリング- 複数モード - gas 3 秒 作業1 W A T E R 作業9 11 2 秒 秒 作業2 作業5 4 秒 2 秒 作業6 4 作業3 秒 2 秒 作業7 4 作業10 秒 作業8 2 4 秒 秒 作業4 1人   3秒 2人   2秒 3人   1秒 3人のピットクルー (資源制約) 資源(機械)制約 があると難しい!

  43. 並列ショップスケジューリング 2 - モードの概念と使用法 - モード:作業を行うための処理方法 例: 作業 「ジュースを買う」 コンビニモード:作業時間 20 分,お金資源 120 円,人資源 1人 自販機モード:作業時間 5 分,お金資源 120 円,人資源 1人 スーパーモード:作業時間 40 分,お金資源 100 円,人資源 1人,車資源 1 台

  44. Pythonインターフェイスによる記述(1) for i in duration: act[i]=m1.addActivity("Act[%s]"%i) if i==1: mode[1,1]=Mode("Mode[1_1]",3) mode[1,1].addResource(res,{(0,"inf"):1}) mode[1,2]=Mode("Mode[1_2]",2) mode[1,2].addResource(res,{(0,"inf"):2}) mode[1,3]=Mode("Mode[1_3]",1) mode[1,3].addResource(res,{(0,"inf"):3}) act[i].addModes(mode[1,1],mode[1,2],mode[1,3]) else: mode[i]=Mode("Mode[%s]"%i,duration[i]) mode[i].addResource(res,{(0,"inf"):1}) act[i].addModes(mode[i]) •  多モードの記述 作業1のモード1 作業1のモード1に 資源を追加 作業1にモード1, モード2,モード3 を追加

  45. Pythonインターフェイスによる記述(2) •  Pythonコードまとめ(1) for i in duration: act[i]=m1.addActivity("Act[%s]"%i) if i==1: mode[1,1]=Mode("Mode[1_1]",3) mode[1,1].addResource(res,{(0,"inf"):1}) mode[1,2]=Mode("Mode[1_2]",2) mode[1,2].addResource(res,{(0,"inf"):2}) mode[1,3]=Mode("Mode[1_3]",1) mode[1,3].addResource(res,{(0,"inf"):3})    act[i].addModes(mode[1,1],mode[1,2],mode[1,3]) else: mode[i]=Mode("Mode[%s]"%i,duration[i]) mode[i].addResource(res,{(0,"inf"):1}) act[i].addModes(mode[i]) from optseq2 import * m1=Model() duration ={1:3, 2:2, 3:2, 4:2, 5:4, 6:4, 7:4, 8:4, 9:11, 10:2 } res=m1.addResource("worker",capacity={(0,"inf"):3}) act={} mode={}

  46. Pythonインターフェイスによる記述(3) •  Pythonコードまとめ(2) m1.addTemporal(act[1],act[9]) for i in range(5,9): m1.addTemporal(act[4],act[i]) m1.addTemporal(act[i],act[10]) m1.Params.TimeLimit=1 m1.Params.OutputFlag=True m1.Params.Makespan=True m1.optimize()

  47. Pythonインターフェイスによる記述(4) objective value = 13 cpu time = 0.00/1.00(s) iteration = 7/7343 source --- 0 0 sink --- 13 13 Act[1] Mode[1_3] 0 1 Act[2] --- 1 3 Act[3] --- 11 13 Act[4] --- 1 3 Act[5] --- 7 11 Act[6] --- 3 7 Act[7] --- 7 11 Act[8] --- 3 7 Act[9] --- 1 12 Act[10] --- 11 13 planning horizon= 13 計算結果とガントチャート

  48. 資源制約付きスケジュールングお家を早く造ろう!資源制約付きスケジュールングお家を早く造ろう! 作業時間=2日1日目1人,2日目2人の資源が必要! 1階 屋根 土台 1人の作業員休暇 完成! 資源量(人) 2人 内装 0 3 時間(日)

  49. 最適解 資源制約付きスケジューリングは一般的なモデル (ジョブショップ,並列ショップスケジューリングを特殊形として含む.)

  50. Pythonインターフェイスによる記述(1) • 資源の必要量入力 m1=Model() duration ={1:1,2:3,3:2,4:2} req={} req[1]={(0,1):2 } req[2]={(0,1):2 ,(1,3):1} req[3]={(0,2):1 } req[4]={(0,1):1,(1,2):2 } res=m1.addResource("worker") res.addCapacity(0,2,2) res.addCapacity(2,3,1) res.addCapacity(3,"inf",2) {(0,1):2 } {(開始時刻,終了時刻):資源必要量 } 土台造り( req[1])は1日目に 資源(人)が2単位必要 • 資源の容量制約入力 (0,2,2)    (開始時刻,終了時刻,資源容量)  最初の2日間は資源(人)が 2単位使用可能

More Related