前提・実現したいこと
Python初心者です。宜しくお願いいたします。
稚拙な説明で申し訳ありませんが、ご指導いただけますと幸いです。
Pythonにてpulpの組合せ最適化を使用しシフト作成を行うことを検討しています。作成するシフトについての条件は次のとおりとなります。
・1チーム5名(A~E)で成り立っています。
・日勤→夜勤→明け→休暇 のローテーションで繰り返される勤務となります。
・日勤でも早番と遅番がありますので、日勤シフトの場合、早番で勤務するメンバーと遅番で勤務するメンバーにわかれています。
作成するシフトについて「0」「1」「2」で表現することとし、「0:休暇」「1:早番」「2:遅番」としたいです。
例として6/20が日勤で「1:早番」が2名「2:遅番」が2名(1名は休暇)のシフト場合、その日の数値の合計値は「6」となりますが、1名は休暇でありますので、4名で「6」を表す場合の組合せは「1」が2名「2」が2名(「0」が1名)となるので、これを制約式で表現したいと思っています。
発生している問題・エラーメッセージ
元々存在していたソースは「0:休暇」「1:出勤」の組合せを制約式にしたものだったのですが、この制約式を修正し、0~2の値を取り得ることと、該当の日における「0:休暇」の人数を制約式として追加することを試みました。
######0~2の値を取り得る
HTML
1for i in range(n_members): 2 for j in range(n_days): 3 model.addConstraint(a.iloc[i,j] <= 2)
######該当の日における「0:休暇」の人数
HTML
1for i in range(n_days): 2 n_rest = num_rest_members[duty_list[i]] 3 for j in range(n_members): 4 if value(a.iloc[j,i]) == 0: 5 x += 1 6 model.addConstraint(x <= n_rest)
実行すると後半部分の制約式に誤りがあり、次のようなエラーが発生します。
TypeError: Can only add LpConstraint objects
該当のソースコード
html
1import numpy as np 2import pandas as pd 3from pulp import * 4from ortoolpy import addvar, addvars, addbinvars 5import random 6import string 7 8model = LpProblem() 9 10n_members = 5 11members = list(string.ascii_uppercase[:n_members]) 12days = range(1, 31) 13n_days = 30 14 15""" 16変数の準備 17""" 18a = pd.DataFrame(addvars(5, 30), index=members, columns=days) 19members = list(string.ascii_uppercase[:n_members]) 20 21num_required_members = {'日勤': 6, '夜勤': 7, '明け': 5, '休暇': 0} 22num_rest_members = {'日勤': 1, '夜勤': 0, '明け': 0, '休暇': 5} 23 24duty_list = ['明け', '休暇', '日勤', '夜勤', '明け', '休暇', '日勤', '夜勤', '明け', '休暇', '日勤', '夜勤', '明け', '休暇', '日勤', '夜勤', '明け', '休暇', '日勤', '夜勤', '明け', '休暇', '日勤', '夜勤', '明け', '休暇', '日勤', '夜勤', '明け', '休暇'] 25 26t = 30 27y = addvar() 28x = addvar() 29""" 30目的関数と制約式 31""" 32model.setObjective(y) 33""" 34各メンバーの出勤日数をなるべく小さくする 35""" 36for i, s in enumerate(a.sum()): 37 model.addConstraint(s - t <= y) 38 model.addConstraint(s - t >= -y) 39 40""" 41取り得る値は0~2 42""" 43for i in range(n_members): 44 for j in range(n_days): 45 model.addConstraint(a.iloc[i,j] <= 2) 46 47""" 48該当の日の数値の合計が一致する。 49""" 50for i in range(n_days): 51 n_mem = num_required_members[duty_list[i]] 52 model.addConstraint(a.iloc[:,i].sum() == n_mem) 53 54""" 55該当の日の休暇(0)の数が一致する。 56""" 57for i in range(n_days): 58 n_rest = num_rest_members[duty_list[i]] 59 for j in range(n_members): 60 if value(a.iloc[j,i]) == 0: 61 x += 1 62 model.addConstraint(x <= n_rest) 63 64model.solve()
試したこと
前述でも記載させていただきましたが、0~2の値を取り得ることと、該当の日における「0:休暇」の人数を制約式として追加することを試みましたが、休暇(0)の数の制御がうまく動作しませんでした。
補足情報(FW/ツールのバージョンなど)
回答1件
あなたの回答
tips
プレビュー