予定半日が入力されることがなければ、GUIだけで実装可能です。
シフト定義です。ラベル半1長と半1夜が長夜差補正項になります。公休は2カウント、長日が多い場合の補正項(ラベル半1長)は、1カウント、夜勤が多い場合の補正項(ラベル半1夜)は、2カウントになります。予定半日は、自動カウントにはしません。
公休数はこれを整数カウントすればOKです。
後は、これを同数カウントすればOKです。パターン01がA、パターン23をBにしています。A==Bになるように制約します。
ここで
A=長日+夜半日
B=夜勤+長半日
です。
Σ(夜半日+長半日)<=1になるようにすれば、Σ(長日-夜勤)<=±1となります。
この制約により、夜半日と長半日は、各々1回以下となります。また、同時に存在することを防止します。
この状態では、±0にしようとする力(センター力)は働きません。できれば、±0にしたい場合は、
Σ(夜半日+長半日)<=0のソフト制約として、エラー許容範囲を1とすれば、よいです。エラー許容を1とすることは、Σ(夜半日+長半日)<=1をハード制約にすることと同じです。
上の考え方の根本は、1日のシフトは、1個しかActiveにならないという基幹制約にあります。
なお、A/Bをそれぞれまとめて、同時制約を次のようにしてもよいです。
0 件のコメント:
コメントを投稿