月二回三人のフロア長会議(夕方)に関しては日勤か夜勤入りにしたいのですがどのようにしたらよろしいでしょうか?
会議の実装例としては、以下があります。
(1)研修・定例会議・休み希望
(2)リーダ会議
(3)看護師勤務表にタスクを追加
のようなタスクを使った実装
が考えられます。(1)は、開催日が決まっている場合であり、(2)(3)については、シフト・タスクの追加が必要であり、プラグインで簡単に取り外せるという訳には行きません。
そこで、今回は、プラグイン方式で、チェックを外すと、何事もなかったかのように動作する実装を考えます。
実装はPythonです。コードをコピペするだけですので、中身の理解が出来なくとも移植は、可能です。
フロア長の定義
次のようにフロア長属性を定義します。
フロア長を設定します。
Pythonコード
下記コードは、制約及びポスト処理でのチェックの二つの部分から成ります。ソフトレベル5で制約化しています。 この結果は、単純な行列結果ではないので、GUIで出力させることが出来ません。なので、ポスト処理で、階を見て候補日をプリントしています。
import sc3
def assign_フロア長会議(会議開催数):
listday=[]
for day in 今月:
list=[]
for person in 全スタッフ:
if person not in フロア長:
continue
v1=sc3.GetShiftVar(person,day,'日勤')
v2=sc3.GetShiftVar(person,day,'入り')
list.append(v1|v2)#日勤または、入り
listday.append(sc3.And(list))#がフロア長全員、日勤または入りの日が、
s='フロア長会議'
sc3.AddSoft(sc3.SeqError(会議開催数,0,3,listday),s,5)#今月、2回以上あること
def check_フロア長会議(希望会議開催数):
success_cnt=0
for day in 今月:
list=[]
success=True
for person in 全スタッフ:
if person not in フロア長:
continue
v=shift_solution[person][day]
if v !='日勤' and v!='入り':#日勤か入りでなければNG
success=False
if success:
print('フロア長会議',daydef[day],'に可能です')
success_cnt+=1
if success_cnt<希望会議開催数:
print('フロア長会議は、指定回数開催できませんでした。')
def post_main():#求解後、呼び出しルーチン
check_フロア長会議(2)
assign_フロア長会議(2) #main 開催数最小値で呼び出しする
チェック出力
次のように、会議が開催可能な候補日が出力されます。
Python プロパティファイルの生成が終わりました。
_____________________________________
| | | |
| Weight | Errors | Cost |
|___________|___________|_____________|
| | | |
| 7 | 0 | 0 |
| 6 | 0 | 0 |
| 5 | 0 | 0 |
| 1 | 0 | 0 |
|___________|___________|_____________|
| | |
| Total | 0 |
|_______________________|_____________|
*********UB=0(0) 3.079(cpu sec)
o 0(0)
解探索が終了しました。 4 (秒)
解が得られました。
ポスト処理を実行します。ソルバを呼び出し中です。
フロア長会議 2023-11-03 に可能です
フロア長会議 2023-11-05 に可能です
フロア長会議 2023-11-13 に可能です
フロア長会議 2023-11-17 に可能です
フロア長会議 2023-11-18 に可能です
フロア長会議 2023-11-25 に可能です
ポスト処理を終了しました。 1 (秒)
求解画面
解
上記候補日が、確かにフロア長会議の要件を満たしていることが分かります。
プロジェクト
プロジェクトは、以下です。
ダウンロード
して、実装の参考にしてください。