■単に制約するだけではなく、予定シフトを読み込んでエラーを出力させています。
予定シフトのエラーが検出を行い、制約エンジンに行く前にエラーを表示させることが出来ます。
別な応用としては、予定シフトとスタッフプロパティを読み込んで、予定シフトが書き込まれていないときに限り、スタッフプロパティによるDefaultシフトを書き込むことが考えられます。
ソフト制約を使えば静的には、実現可能ですが、動的に判断した方が、余計なソフトエラーはなくなりメンテナンス性が良くなる場合もあります。
import sc3
def 半代休設定():
for person in 全スタッフ:
vlist=[]
s='言語公休回数'+' '+staffdef[person]+'\n'
土WORKCNT=[]
日WORKCNT=[]
代CNT=[]
半CNT=[]
for day in 今月:
v=sc3.GetShiftVar(person,day,'訪問')
vD=sc3.GetShiftVar(person,day,'代休')
vH=sc3.GetShiftVar(person,day,'半休')
if day in 土:
土WORKCNT.append(v)
sc3.AddHard(~vD,'土曜日は代休なし'+str(person))
sc3.AddHard(~vH,'土曜日は半休なし'+str(person))
elif day in 日:
日WORKCNT.append(v)
sc3.AddHard(~vD,'日曜日は代休なし'+str(person))
sc3.AddHard(~vH,'日曜日は半休なし'+str(person))
else:
代CNT.append(vD)
半CNT.append(vH)
vlist.append(v)
sc3.AddHard(sc3.SeqComp(半CNT,土WORKCNT),'seqComp+str(person)')
sc3.AddHard(sc3.SeqComp(代CNT,日WORKCNT),'seqComp+str(person)')
def 訪問3日連続チェック():
for person in 全スタッフ:
for day in 全日:
if day<制約開始日:
continue
ts=shift_schedules[person][day][0]#予定シフトを読み取る タプル1は、ソフトレベル
tsy=shift_schedules[person][day-1][0]#予定シフトを読み取る タプル1は、ソフトレベル
tsyy=shift_schedules[person][day-2][0]#予定シフトを読み取る タプル1は、ソフトレベル
s='3連続訪問禁止'+staffdef[person] +' '+ daydef[day] +'\n'
if ts=='訪問' and tsy=='訪問' and tsyy=='訪問':
sc3.print( '*****3連続訪問エラーがあります。'+s)#エラー出力
x0=sc3.GetShiftVar(person,day,'訪問')
x1=sc3.GetShiftVar(person,day-1,'訪問')
x2=sc3.GetShiftVar(person,day-2,'訪問')
sc3.AddHard(~x0 | ~x1 | ~x2,s)#ハード制約 3連続訪問禁止
半代休設定()
訪問3日連続チェック()