前提・実現したいこと
PythonのPuLPを用いて勤務表の生成ソフトを作っています。
発生している問題
勤務をバラバラに割り当てるコードを作成しました。
休みがいることが前提ですので勤務は割り振られない人(Free)がいます。
午前、午後ともにActionは全て割り振られなくてはいけません。
①勤務には午前に1AMをやったら午後は2PM、
前日の午後が3PMならば翌日午前は4AMといった依存関係があります。
それをどういった条件式として表現すればいいかできないでいます。
②目的関数として何を設定するのが適切なのかわかりません。
各々は独立しているので、なるべくバラバラに勤務が作成されることが目的ですが、それが条件にできないので
コードでは仮の目的としてAAAさんの午前勤務を最低にすると設定しています。
ソースはネット上の情報を改変したもので、PuLPへの理解は全く不十分な状況で申し訳ありませんが、
わかる人いましたら、教えていただけますと大変助かります。
該当のソースコード
Python
1import pulp 2 3Member = ['AAA', "BBB", "CCC",'DDD','EEE','FFF','GGG','HHH','III','JJJ','KKK','LLL'] 4Day = ["1", "2", "3", "4", "5",'6','7','8','9','10'] 5AM_Action = ['1AM','2AM','3AM','4AM','5AM','6AM','7AM','8AM','9AM'] 6PM_Action = ['1PM','2PM','3PM','4PM','5PM','6PM','7PM','8PM','9PM','10PM'] 7 8#問題の宣言 9ShiftScheduling = pulp.LpProblem("ShiftScheduling", pulp.LpMinimize) 10 11#変数の宣言 12x = {} 13for m in Member: 14 for d in Day: 15 for am in AM_Action: 16 x[m, d, am] = pulp.LpVariable("x({:},{:},{:})".format(m,d,am), 0, 1, pulp.LpInteger) 17 18for m in Member: 19 for d in Day: 20 for pm in PM_Action: 21 x[m, d, pm] = pulp.LpVariable("x({:},{:},{:})".format(m,d,pm), 0, 1, pulp.LpInteger) 22 23#目的関数:AAAさんの勤務を最低にする(仮の目的) 24ShiftScheduling += pulp.lpSum(x['AAA', d, am] for d in Day for am in AM_Action), "Target" 25 26# それぞれの勤務に1人割り当てられる。 27for d in Day: 28 for am in AM_Action: 29 ShiftScheduling += pulp.lpSum(x[m,d,am] for m in Member) == 1, "AM_Constraint_{:}_{:}".format(d,am) 30 31for d in Day: 32 for pm in PM_Action: 33 ShiftScheduling += pulp.lpSum(x[m,d,pm] for m in Member) == 1, "PM_Constraint_{:}_{:}".format(d,pm) 34 35# 対応不可能日 36NG = [['AAA','1','3AM'],['BBB','2','3PM'],['DDD','3','5AM'],['DDD','4','5PM'],['EEE','5','6PM']] 37 38for m, d, a in NG: 39 ShiftScheduling += x[m, d, a] == 0, "Constraint_NG_{:}_{:}_{:}".format(m,d,a) 40 41# 1人は重複せず勤務に割り当てられる。 42for m in Member: 43 for d in Day: 44 n_act = pulp.lpSum(x[m,d,am] for am in AM_Action) 45 ShiftScheduling += n_act <= 1,"Constraint_am_{:}_{:}".format(m,d) 46 47for m in Member: 48 for d in Day: 49 n_act = pulp.lpSum(x[m,d,pm] for pm in PM_Action) 50 ShiftScheduling += n_act <= 1,"Constraint_pm_{:}_{:}".format(m,d) 51 52results = ShiftScheduling.solve() 53print("optimality = {:}, target value = {:}".format(pulp.LpStatus[results], pulp.value(ShiftScheduling.objective))) 54 55#結果の確認。適当なコードで申し訳ありません。 56for m in Member: 57 line = '{} '.format(m) 58 for d in Day: 59 sum = 0.0 60 for am in AM_Action: 61 if x[m,d,am].value() == 1.0: 62 line = line + am + '-' 63 sum += x[m,d,am].value() 64 if sum == 0.0: 65 line = line + 'Free-' 66 sum = 0.0 67 for pm in PM_Action: 68 if x[m,d,pm].value() == 1.0: 69 line = line + pm + ' ' 70 sum += x[m,d,pm].value() 71 if sum == 0.0: 72 line = line + 'Free ' 73 print(line) 74
試したこと
Python
1# 午前中1AMをやった人は午後は2PMになる。 2#一応コードを作ってみましたが、当然のごとく全く機能しません。 3for m in Member: 4 for d in Day: 5 am_act = x[m,d,'1AM'] 6 pm_act = x[m,d,'2PM'] 7 ShiftScheduling += am_act + pm_act == 1 , "Constraint_2after1_{:}_{:}".format(m,d)
補足情報(FW/ツールのバージョンなど)
Python 3.9.1
PuLP 2.4
あなたの回答
tips
プレビュー