残念ながら、機械的・画一的方法はありません。が、概略こうした手順で行けば上手くいくことが多い、という方法はあります。
その手順を、実際にお客さまから頂いた仕様を制約に落とす例で、見ていきましょう。
最初に頂いた仕様は、以下の通りの文章です。これをいきなり制約に落とせる人は、私を含めていないと思います。
仕様:
2 平日の場合の制約
(1)日勤は7名(チームは問わない)が必要
(2)夜勤専従16(夜16)1名が勤務しない場合
ア 新人看護師に長日勤(長日)及び夜勤(夜)を割り当てない場合
(ア)長日勤(長日)は、Aチーム及びBチームから各1名、A又はBのどちらかのチームから1名、合計3名が必要
(イ)夜勤(夜)は、Aチーム及びBチームから各1名、A又はBのどちらかのチームから1名、合計3名が必要
イ 新人看護師に長日勤(長日)を割当て、夜勤(夜)を割当てない場合
(ア)長日勤(長日)は、Aチーム及びBチームから各1名、A又はBのどちらかのチームから1名及びA又はBのどちらかのチームからの新人看護師1名の合計4名を割当てる。
(イ)夜勤(夜)は、Aチーム及びBチームから各1名、A又はBのどちらかのチームから1名、合計3名が必要
ウ 新人看護師に長日勤(長日)の割当てが無く、夜勤(夜)を割当てる場合
(ア)長日勤(長日)は、Aチーム及びBチームから各1名、A又はBのどちらかのチームから1名、合計3名が必要
(イ)夜勤(夜)は、Aチーム及びBチームから各1名、A又はBのどちらかのチームから1名及びA又はBのどちらかのチームからの新人看護師1名の合計4名を割当てる。
エ 新人看護師に長日勤(長日)及び夜勤(夜)を割り当てる場合
(ア)長日勤(長日)は、Aチーム及びBチームから各1名、A又はBのどちらかのチームから1名及びA又はBのどちらかのチームからの新人看護師1名の合計4名を割当てる。
(イ)夜勤(夜)は、Aチーム及びBチームから各1名、A又はBのどちらかのチームから1名及びA又はBのどちらかのチームからの新人看護師1名の合計4名を割当てる。
(ウ)新人看護師に長日勤(長日)及び夜勤(夜)を割当てる場合は、A又はBチームからそれぞれ1名の割当てとする。
(3)夜勤専従16(夜16)1名が勤務する場合
ア 新人看護師に長日勤(長日)及び夜勤(夜)を割り当てない場合
(ア)長日勤(長日)は、Aチーム及びBチームから各1名、合計2名が必要
(イ)夜勤(夜)は、Aチーム及びBチームから各1名、合計2名が必要
イ 新人看護師に長日勤(長日)を割当て、夜勤(夜)を割当てない場合
(ア)長日勤(長日)は、Aチーム及びBチームから各1名、A又はBのどちらかのチームからの新人看護師1名の合計3名を割当てる。
(イ)夜勤(夜)は、Aチーム及びBチームから各1名、合計2名が必要
ウ 新人看護師に長日勤(長日)の割当てが無く、夜勤(夜)を割当てる場合
(ア)長日勤(長日)は、Aチーム及びBチームから各1名、合計2名が必要
(イ)夜勤(夜)は、Aチーム及びBチームから各1名、A又はBのどちらかのチームから1名及びA又はBのどちらかのチームからの新人看護師1名の合計4名を割当てる。
エ 新人看護師に長日勤(長日)及び夜勤(夜)を割り当てる場合
(ア)長日勤(長日)は、Aチーム及びBチームから各1名、A又はBのどちらかのチームからの新人看護師1名の合計3名を割当てる。
(イ)夜勤(夜)は、Aチーム及びBチームから各1名、A又はBのどちらかのチームからの新人看護師1名の合計3名を割当てる。
(ウ)新人看護師に長日勤(長日)及び夜勤(夜)を割当てる場合は、A又はBチームからそれぞれ1名の割当てとする。
<手順その1:表にする>
最初にやることは、表にすることです。表にすることで、何と何がパラメータで欲しい人数は、何なのか?が見えてきます。また、足りない記述も見えてきます。
上表は、上の文章を表にまとめたものです。空欄部は、文章からは読み取れない箇所です。
新人の有無、夜勤専従者の有無、休日・平日で、夜勤者と長日勤者の数が変化することが分かります。
<手順その2:表を埋める>
ブランク部は、記述がない、もしくは不確かな部分になります。このように、表にすることによって、記載の漏れや、考え方の足りない部分など、強制的に考えざるを得ない状況となります。また、考えうる全てのケースについて強制的に考えざるをえなくなります。ブランク部は、再度問い合わせをして、回答を以下のように頂きました。
<手順その3:ルール(制約)を考える>
既に記してありますが、次に考えるのはルール(制約)です。考えるべきは、この表の全てに当てはまる、共通ルールは何か?ということになります。初期、新人の有無がパラメータになると考えましたが、本質的には、上に記されている通り、
■夜勤専従(夜16)の勤務は、正職員の看護師の長日と夜勤の1名分に相当するといえる。
■新人看護師の長日と夜勤の勤務は、長日及び夜勤で必要とされる人数にはカウントしない
ということが表で共通するルールになっています。これは、私が類推したものではなく、お客さま自身が気づき、それにより誤記訂正までされています。つまり、表にすることは、仕様の整理にもなります。看護師勤務表で難しいのは、複雑なルールで絡み合っていることです。そこを整理しないで、制約化は誰にも(私を含めてAIにも)できません。なぜなら、欲しい仕様を分かっていないのは、実は、お客さまご自身である可能性があるからです。
お客さまご自身が、仕様を整理することが重要です。ここが間違っていると、間違った解しか出てきません。間違っているかどうかは、お客さまご自身しか分かりません。私の方では、仕様は、全て実現させる、という方針で設計するので、変則的ルールだな?という違和感は確かにこの場合もありましたが、間違いの指摘までには至りません。
<手順その4:ルールを制約し易い表現にコンバートする>
次に行うことは、スケジュールナース上の制約表現に変更することです。
上表でも既に書いていますが、本質的なのは、
■夜勤専従+新人以外の勤務者==3
ということです。これは、長日勤でも、夜勤でも変わりません。このように
〇何かと何かを足すと定数
という関係を見つけます。3・4名に分散している数の項目ではなく、定数となるルールそれが、一番欲しい関係です。それさえ見つかれば、列制約で記述できます。
<手順その5:列制約記述>
例えば、新人が2人不可→新人は、最大1名以下というスケジュールナース制約に記述できます。他も同様です。
<手順その6:ペア制約 列制約で記述不能の場合のみ>
列制約で記述を網羅できれば、必要ありません。今回の場合、
新人が入ったときとそうでないときで、遅日勤の数が異なります。ケース毎に必要人数が異なる場合は、列制約では記述できないので、「AならばB」のペア制約を使うことになります。ペア制約は、二つあり、「禁止」と「AならばB」制約です。禁止は、列制約でも代替可能ですが、「AならばB」制約は、ペア制約でしか記述できません。使い方は、列制約に比べて難しいので、可能な限り列制約で記述することをお勧めします。
以上が、一般的な手順です。
ペア制約は難しいと思いますが、それ以外は、全部ご自分で記述できるようになる・なれると思います。
ここまで出来るようになれば、殆どの場合、メンテナンス作業もご自分で出来るようになると思います。