制約計画ソルバー SCOP Solver for COnstraint Programming:スコープ Pythonモジュールの使い方 SCOP.pyモジュールとは • 制約計画ソルバーSCOPを,超高級言語 Pythonから直接呼び出して,求解するための モジュール • すべてPythonで書かれたクラスで構成 • ソースコード(すべてPythonで記述)も公開さ れているので,ユーザが書き換え可能 Pythonモジュールのクラス • 問題クラス Problem • 制約クラス (Constraint) – 線形制約クラス Linear – 2次制約クラス Quadratic – 相異制約クラス Alldiff 問題クラス Problem(1) • オブジェクト生成の例(pという問題例を生成) p=Problem() • メソッド – addVariable(変数名 =文字列,領域=リスト) 変数を1つ問題に追加する. – addVariables(変数のリスト,領域=リスト) リストに含まれる変数(複数)を一度に問題に追加する. 例:p.addVariable(“Worker A”, [“Do Job1”,”Do Job2” ]) (作業員AはJob1かJob2を行う.) 例: p.addVariables([“A”, “B”], [“Do Job1”,”Do Job2” ]) (作業員 A,B は Job1かJob2を行う.) 問題クラス Problem(2) • メソッド – addConstriant(制約オブジェクト) 制約オブジェクトを問題に追加する. – setTarget(目標値=整数:規定値0) ペナルティ逸脱量の合計が,ここで指定した目標値以下 になったら探索が終了する. – solve(time=制限時間:規定値600,seed=乱数の種:規定 値1): 求解する.返値は,解(変数名をキー,値を領域から選ば れた値とした辞書)と逸脱した制約(制約名をキー,逸脱 量を値とした辞書)のタプル 問題クラス Problem(3) Problemクラスは,文字列を返すメソッドが定義され ている. print 問題のオブジェクト 変数の数,制約の数,制約の情報を画面上に出力 する. 線形制約クラス • オブジェクト生成 Linear(制約名=文字列,weight=1:既定値) 例:con1=Linear(“L1”,100) • メソッド – addTerm(係数=整数,変数名 =文字列,値=数値,文字 列) 左辺の項を1つ制約に追加する. – setRhs(右辺定数=整数) 線形制約の右辺定数を設定する.規定値は0 – setDirection(制約の向き = ”<=“,”>=“,”=“のいずれか) 制約の向きを設定する.規定値は”<=“ – setWeight(重み=正数もしくは”inf”) 制約の重みを設定する.”inf”は無限大(絶対制約)を示す. 2次制約クラス • オブジェクト生成 Quadratic(制約名=文字列,weight=1:既定値) 例:con1=Quadratic(“Q1”,10) • メソッド – addTerm(係数,変数名1,値1,変数名2,値2) 左辺の2次の項を1つ制約に追加する. – setRhs(右辺定数=整数) 線形制約の右辺定数を設定する.規定値は0 – setDirection(制約の向き = ”<=“,”>=“,”=“のいずれか) 制約の向きを設定する.規定値は ”<=“ – setWeight(重み=正数もしくは”inf”) 制約の重みを設定する.”inf”は無限大(絶対制約)を示す. 相異制約クラス • オブジェクト生成 Alldiff(制約名=文字列,変数名のリスト:規定値は空 のリスト,重み=1:既定値) 例:con1=Alldiff(“all_diff”,[“A”,”B”,”C”],”inf”) • メソッド – addVariable(変数名 =文字列) 相異制約の変数を1つ制約に追加する. – addVariables(変数名リスト =文字列のリスト) 相異制約の変数を複数同時に追加する. – setWeight(重み=正数もしくは”inf”) 制約の重みを設定する.”inf”は無限大(絶対制約)を示す. 仕事の割当の例 • 3人の作業員 A,B,C を3つ の仕事 0,1,2 に割り当てる. • 割当費用= 0 1 2 A 15 20 30 B 7 15 12 C 25 10 13 割当はAlldiff制約,費用は線形制約 import scop scopモジュールを読み込む p=scop.Problem() 問題オブジェクトpを生成 workers=["A","B","C"] Cost=[[15, 20, 30],[7, 15, 12],[25,10,13]] 変数の追加 p.addVariables(workers,range(3)) 相異制約オブジェクトcon1の生成 con1=scop.Alldiff("all_diff_constraint",workers, weight=”inf”) 線形制約オブジェクトcon2の生成 con2=scop.Linear("linear_constraint") for i in range(len(workers)): for j in range(3): 線形制約に左辺の項を追加 con2.addTerm(Cost[i][j],workers[i],j) con2.setRhs(0) 右辺定数の設定 con2.setDirection(“<=”) 制約の方向の決定 相異制約を問題に追加 p.addConstraint(con1) 線形制約を問題に追加 p.addConstraint(con2) 求解(時間制限3秒) sol,violated=p.solve(time=3) print "solution“ for x in sol: 結果(解)の辞書を表示 print x,sol[x] print "violated constraint(s)" for v in violated:結果(破られた制約)の辞書を表示 print v,violated[v] 実行結果 solution 解の表示 A0 C1 B2 violated constraint(s) 逸脱した制約の表示 linear_constraint 37 問題情報の出力 print p とすると... number of variables = 3 number of constraints= 2 variable A:[0, 1, 2] variable B:[0, 1, 2] variable C:[0, 1, 2] Alldiff: all_diff_constraint: weight=inf ACB Linear: linear_constraint: weight=1 15*x[A:0] 20*x[A:1] 30*x[A:2] 7*x[B:0] 15*x[B:1] 12*x[B:2] 25*x[C:0] 10*x[C:1] 13*x[C:2] <=0 仕事の割当の例(2) • 5人の作業員 A,B,C,D,E を3つ の仕事 0,1,2 に割り当てる. • 仕事の必要人数=(1,2,2)人 • 割当費用= 0 1 2 A 15 20 30 B 7 15 12 C 25 10 13 D 15 18 3 E 5 12 17 import scop p=scop.Problem() workers=["A","B","C","D","E"] Cost=[[15, 20, 30],[7, 15, 12],[25,10,13],[15,18,3],[5,12,17]] LB=[1,2,2] p.addVariables(workers,range(3)) LB_Constraint={} for j in range(3): LB_Constraint[j]=scop.Linear("LB_constraint"+str(j),"inf") for i in range(len(workers)): LB_Constraint[j].addTerm(1,workers[i],j) LB_Constraint[j].setRhs(LB[j]) LB_Constraint[j].setDirection(">=") p.addConstraint(LB_Constraint[j]) con1=scop.Linear("linear_constraint") for i in range(len(workers)): for j in range(3): con1.addTerm(Cost[i][j],workers[i],j) p.addConstraint(con1) sol,violated=p.solve(time=1) print "solution" for x in sol: print x,sol[x] print "violated constraint(s)" for v in violated: print v,violated[v] SCOPによる求解 solution A1 C1 B2 E0 D2 violated constraint(s) linear_constraint 50 50 (=20+12+10+3+5) 万円 0 1 2 A 15 20 30 B 7 15 12 C 25 10 13 D 15 18 3 E 5 12 17 仕事の割当の例(3) • 5人の作業員 A,B,C,D,E を3つの仕事 0,1,2 に割り 当,必要人数は(1,2,2)人(前の例と同じ) • 作業員AとCは仲が悪いので,異なる仕事に割り振る • 割当費用= 0 1 2 A 15 20 30 B 7 15 12 C 25 10 13 D 15 18 3 E 5 12 17 作業員A,Cが同じ仕事をしない 制約の記述 作業員 A とCを同じ仕事に割り当てることを禁止する2次制約 (重みは 100) con2=scop.Quadratic("quadratic_constraint",100) for j in range(3): con2.addTerm(1,"A",j,"C",j) p.addConstraint(con2) SCOPによる求解 solution A0 C1 B2 E1 D2 violated constraint(s) linear_constraint 52 52 (=15+12+10+3+12) 万円 0 1 2 A 15 20 30 B 7 15 12 C 25 10 13 D 15 18 3 E 5 12 17
© Copyright 2024 ExpyDoc