前回から引き続き、
■3交代、準夜が居た場合、同じチームで、翌日深夜が居ること
■3交代、深夜が居た場合に、同じチームで、前日に準夜が居ること
この要件は、3交代の勤務を考えた場合、必然となります。日勤を除く時間帯16時間を誰かが埋めないといけない、ということです。
この職場の場合、チームは、A/Bの2チームで、3交代が各々1名居ります。なので、
■Aチーム3交代準夜が居れば、翌日Aチーム2交代深夜が居ること
■Bチーム3交代準夜が居れば、翌日Bチーム2交代深夜がいること
になります。同様に、
■Aチーム3交代深夜が居れば、前日Aチーム2交代準夜が居ること
■Bチーム3交代深夜が居れば、前日Bチーム2交代準夜がいること
が、制約になります。
「居ること」の真意は、「少なくとも一人居ること」ですから、ORで、演算子「または」を用いて実装できます。(具体的な深夜準夜人数については、列制約で制約しています。)
また、「前日」が必要ですから、「制約開始日1日前から」を使えば、先月からの流れも問題ありません。翌日に対しては、+1、前日に対しては、ー1を「日オフセット」で指定すればOKです。
以上を実装したのが、次になります。
「AならばB」で気を付けること
「AならばB」制約は、難しいので、使わないで済むならば、使いたくはないです。
今回の場合のように、使わなくては記述できないので、使わざるを得ないのですが、その際、気を付けることがあります。それは、
「Aでないときは、何も制約していない」
ということです。言葉通り、Aならば、Bになるのですが、その反対の、Aでないならば、
の状態のとき、Bがどうなるかは、何も制約されていないということです。
今回の例で言えば、3交代深夜が居ないときに、2交代準夜が居てもおかしくない、ということが起きてしまいます。
つまり、茶色枠の制約だけでは、上の事象が起きてしまう可能性があります。本当は、どういう風にしたいかというと、
■Aチーム3交代準夜が居ないならば、翌日Aチーム2交代深夜が居ない
という風にしたい訳です。なので、茶色枠の4つの制約に対して、さらに4つの制約を加えています。これで初めて、意図した動きになると思います。本質的な意図は、
準夜人数==翌日深夜人数
ということなので、AならばBを使うと、両方向から制約する必要がある、ということです。(多分、リニアペア制約を使えば、上の制約をダイレクトに制約出来ると思います。)
まとめとして、
「AならばB」制約では、Aでないときどうしたいか?も考える
ということがポイントになります。フリーで良いならば片方向でよく、フリーではまずいということであれば、両方向で制約する必要があります。
結構難しい制約です。今回は、Aチーム、Bチーム一人づつの3交代での記述になるのですが、この条件が崩れた場合は、また記述しなおす必要があります。これをメンテナンスしていくのは、なかなか大変そう..と思います。
全員が同じ変則2交代に移行してくれれば、上のような面倒な制約は、必要ありません。
特殊な事例ですが、このような例は、他の地方公立病院でもありそうな話ではあると思います。