Ans.まず、グループ定義で「新人属性」を定義します。新人属性の一要素として「新人」を定義します。
<欲しい集合は、グループ集合で作成>
Ans.まず、グループ定義で「新人属性」を定義します。新人属性の一要素として「新人」を定義します。
First Orderのリニアソルバは、前にも評価しました。HIGHS版では、PDLPのGPU版もあるのですが、Google OR-TOOLS版では、また別な改善がされているということなので評価してみました。
Scaling up linear programming with PDLP
が、残念なことに、「収束速度、精度から言って、問題がある」、INRC2や、SchedulingBenchmarksの記録更新用途には、使用に耐えないという結論に達しました。問題の性質上、Barrior Solver(内点法)によるソルバが有効である、というのは分かっていて、HIGHSの改善版
Funding for the IPM solver and beyond
を待っていたのですが、一向に出る気配がないので諦めてCOPTに依頼することにしました。
NEOSサーバ上のCOPTは、Simplexなので遅いです。CLPと大差ありません。
しかし内点法によるMittlemanBenchmarkによれば、圧倒的に1位です。
Ans. 次のように、休日の集合で2連休パターンを作り、パターン最初の曜日を「土」にします。最小を1としてソフト制約にすれば、「出来れば1回以上」になります。
これだけでOKです。<「出来れば、土日2連休」は、「明け後なるべく2連休」と深く関わっている>
ちなみに、この制約は、「明けの後はなるべく2連休」という制約と関係があり、この制約追加によって、「明けの後はなるべく2連休」制約の実現が難しくなります。
下図は、その様子です。土日休み1回以上が全スタッフ達成しているのに対して、「明けの後の2連休が、かなりの部分出来ていません。スタッフによっては、4になっているところがありますが、これは、4回エラーつまり、夜勤4回も2連休ではなかった、ということになります。
一応、今月とANDを取っておきます。この作業は無くても可です。
なので、単純に追加の記述のみでOKです。(包含関係になければ、単純な追加では済みません。)
Ans. ハード制約化すればよいです。
以下は、行制約レベル4でソフト制約されて例で、そのエラー許容量=0とすればよいです。ただし、ハード制約化することによって「解がない」状態になるリスクがあることに注意してください。
Ans.
どれをシフトにして、どれをその別名とするかは、何を管理対象とするか?に依存します。
例えば、その日の日勤者を何名以上、という風にしたい場合は、日勤という勤務を管理する必要があることになります。その場合、何を日勤と定義するか?は、職場に依存します。フルタイムで働く場合に、日勤とするのは依存ないと思います。時間休が1時間の場合の記号「年7」、時間休が2時間の「年6」を、日勤者のカウントに入れる場合は、日勤の別名にすればよいでしょう。要するに、日勤者としてカウントする勤務をシフト「日勤」に代表させて、別名ラベルを割り当てれば良い訳です。
一方、日勤とはカウントしたくない勤務、例えば「年2」があったとすれば、「研修」というシフトを用意しておいて、その別名として、「年2」としておくとよいでしょう。「研修」を日勤者カウントしないようにしておけば、目的の管理が実現できるでしょう。
このように、何を管理対象とするか?でシフトの定義が変わってきます。例えば、管理単位が「半日」もしくは、「時間」であれば、シフト定義を変える必要があります。
しかし、通常の制約は、日勤者数、夜勤者数といった単純な仕様が殆どだと思いますので、最初に述べた方法で良いと思います。別名を駆使して、シフト状態数を減らすことは、求解速度の面で好ましいです。