# 制約条件の定義 # 1. 各科目は1つの時間スロットに配置される for s in subjects: prob += pl.lpSum([vars[t][s][ts] for t in teachers for ts in time_slots]) == 1
# 2. 各教師は1つの時間スロットで1つの科目のみ教える for t in teachers: for ts in time_slots: prob += pl.lpSum([vars[t][s][ts] for s in subjects]) <= 1
# 3. 教師は教えられる科目のみ教える for t in teachers: for s in subjects: if s notin teacher_subjects[t]: for ts in time_slots: prob += vars[t][s][ts] == 0
# 問題の解決 prob.solve()
# 結果の表示 print("Status:", pl.LpStatus[prob.status]) for t in teachers: for s in subjects: for ts in time_slots: ifvars[t][s][ts].varValue == 1: print(f"{t} will teach {s} at {ts}")
vars[t][s][ts] は、教師 t が科目 s を時間スロット ts に教えるかどうかを示すバイナリ変数です。
$0 $または$ 1 $の値を取ります。
4. 制約条件の定義
4.1 各科目は1つの時間スロットに配置される
1 2 3
# 1. 各科目は1つの時間スロットに配置される for s in subjects: prob += pl.lpSum([vars[t][s][ts] for t in teachers for ts in time_slots]) == 1
説明:
各科目 s は、全ての教師と時間スロットに対して、ちょうど1回だけ教えられることを保証する制約です。 lpSum 関数を使って、全ての教師と時間スロットにわたる変数の合計が$1$になるようにします。
4.2 各教師は$1$つの時間スロットで$1$つの科目のみ教える
1 2 3 4
# 2. 各教師は1つの時間スロットで1つの科目のみ教える for t in teachers: for ts in time_slots: prob += pl.lpSum([vars[t][s][ts] for s in subjects]) <= 1
説明:
各教師 t は、特定の時間スロット ts で、最大1つの科目 s を教えることを保証する制約です。
lpSum 関数を使って、各時間スロットにおける変数の合計が$1$以下になるようにします。
4.3 教師は教えられる科目のみ教える
1 2 3 4 5 6
# 3. 教師は教えられる科目のみ教える for t in teachers: for s in subjects: if s notin teacher_subjects[t]: for ts in time_slots: prob += vars[t][s][ts] == 0
説明:
各教師 t は、自分が教えることができない科目 s を教えないことを保証する制約です。teacher_subjects 辞書を参照し、教師が教えられない科目に対する変数を$0$に設定します。
5. 問題の解決
1 2
# 問題の解決 prob.solve()
説明:
定義された問題を解決します。
PuLP の solve メソッドを使って、最適な解を見つけます。
6. 結果の表示
1 2 3 4 5 6 7
# 結果の表示 print("Status:", pl.LpStatus[prob.status]) for t in teachers: for s in subjects: for ts in time_slots: ifvars[t][s][ts].varValue == 1: print(f"{t} will teach {s} at {ts}")
# 結果の表示 for i inrange(N): print(f"Optimal value for x[{i}]:", model.x[i]()) print("Optimal objective value:", model.objective())
[実行結果]
Optimal value for x[0]: 0.0
Optimal value for x[1]: 0.0
Optimal value for x[2]: 0.0
Optimal value for x[3]: 0.0
Optimal value for x[4]: 10.0
Optimal objective value: 50.0
# 目的関数の定義 model.objective = Objective(expr=sum(coefficients[i] * model.x[i] for i inrange(N)), sense=maximize)
# 制約条件の定義 model.constraints = ConstraintList() for con in constraints: model.constraints.add(sum(con[i] * model.x[i] for i inrange(N)) <= con[-1])
# CBCソルバーを使用する場合 solver = SolverFactory('cbc', executable='/usr/bin/cbc') result = solver.solve(model)
# 結果の表示 print("CBC solver results:") for i inrange(N): print(f"Optimal value for x[{i}]:", model.x[i]()) print("Optimal objective value:", model.objective())
[実行結果]
CBC solver results:
Optimal value for x[0]: 0.0
Optimal value for x[1]: 0.0
Optimal value for x[2]: 0.0
Optimal value for x[3]: 0.0
Optimal value for x[4]: 10.0
Optimal objective value: 50.0
# 変数の定義 vars = pulp.LpVariable.dicts("Route", (warehouses, stores), lowBound=0, cat='Continuous')
# 目的関数の定義 model += pulp.lpSum([vars[w][s] * costs[w][s] for w in warehouses for s in stores]), "Total Cost"
# 制約条件の定義 for w in warehouses: model += pulp.lpSum([vars[w][s] for s in stores]) <= supply[w], f"Supply_{w}"
for s in stores: model += pulp.lpSum([vars[w][s] for w in warehouses]) >= demand[s], f"Demand_{s}"
# 問題を解く model.solve()
# 結果の表示 print(f"Status: {pulp.LpStatus[model.status]}") for w in warehouses: for s in stores: print(f"Route {w} to {s}: {pulp.value(vars[w][s])} units") print(f"Total Cost: {pulp.value(model.objective)}")
[実行結果]
Status: Optimal
Route A to X: 250.0 units
Route A to Y: 0.0 units
Route A to Z: 50.0 units
Route B to X: 0.0 units
Route B to Y: 350.0 units
Route B to Z: 50.0 units
Total Cost: 1250.0
# 各セルに1から9の値を割り当てる for row in rows: for col in cols: problem.addVariable((row, col), range(1, 10))
# 各行に対して全ての数が異なるように制約 for row in rows: problem.addConstraint(AllDifferentConstraint(), [(row, col) for col in cols])
# 各列に対して全ての数が異なるように制約 for col in cols: problem.addConstraint(AllDifferentConstraint(), [(row, col) for row in rows])
# 各3x3のボックスに対して全ての数が異なるように制約 for box_row inrange(3): for box_col inrange(3): cells = [(row, col) for row inrange(box_row*3+1, box_row*3+4) for col inrange(box_col*3+1, box_col*3+4)] problem.addConstraint(AllDifferentConstraint(), cells)
# 解を取得 solutions = problem.getSolutions()
# 解の表示(最初の解のみ) if solutions: solution = solutions[0] for row in rows: print([solution[(row, col)] for col in cols]) else: print("No solution found.")
machines_count = 3 all_tasks = {} machine_to_intervals = [[] for _ inrange(machines_count)] horizon = sum(task[1] for job in jobs_data for task in job)
machines_count = 3 all_tasks = {} machine_to_intervals = [[] for _ inrange(machines_count)] horizon = sum(task[1] for job in jobs_data for task in job)
Optimal Schedule Length: 11
Job 0:
Task 0 starts at 2 and ends at 5
Task 1 starts at 5 and ends at 7
Task 2 starts at 7 and ends at 9
Job 1:
Task 0 starts at 0 and ends at 2
Task 1 starts at 2 and ends at 3
Task 2 starts at 7 and ends at 11
Job 2:
Task 0 starts at 0 and ends at 4
Task 1 starts at 4 and ends at 7