2023年10月31日火曜日

看護師勤務表にタスクを追加

シフト勤務表で、状態が足りないときがあります。

例えば、看護師・介助員のうち、以下のタスクを割り当てる場合です。

介助員ができるのは、介助タスクだけです。しかし、看護師は、そのスキルによって、

以下の全部を出来る人もいれば、スタッフナースタスクだけしかできない、という人も存在します。

□リーダタスク

□介助タスク

□スタッフナースタスク

そうした場合に、看護師が割り当てられたタスクが、上のどれかを判別するには、シフト情報だけでは不足しています。具体的には、夜勤、深夜、準夜用に、各ナースに各タスクが明示的に割り当てられる必要があります。

そうした場合、全部をシフトで行うやり方がありますが、得策ではありません。途端に状態数が爆発してしまうからです。解決策としては、タスク勤務表化があります。本プロジェクト例は、シフト勤務表から、上記のタスクを追加するタスク勤務表にするデモプロジェクトです。

本当にシフト関連には、一切手をつけずに、タスク追加だけで、出来てしまいました。

こうした例は、他に、

■同じようなシフトを持つ複数の棟をタスクにする

■応援先をタスクにする

■医師当直表の 夜勤タスク

等の例があります。

いずれもシフトでは状態特定するので、タスクになっています。タスクとシフトは分離しているので、将来、棟が増えたり、応援先が増えたり、夜勤タスクが増えたとしても、タスク部分だけを追加すればよいことになるので、メンテナンス性が良いのです。

看護師勤務表にタスクを追加 (nurse-scheduling-software.com)




2023年10月29日日曜日

医師当直勤務表に関して寄稿頂きました

勤務表を見るまでは、シフト勤務のブラック度は、

介護>看護師>その他

の順だと思っていたのですが、実は、勤務医がそのトップではないか?と思うようになりました。勿論、診療科によるとは思いますが、その実態を知っていただくべくお願いをして書いて頂きました。忙しいなか、書いて頂きありがとうございました。


医師当直表 スケジュールナースに関する寄稿 (nurse-scheduling-software.com)


2023年10月28日土曜日

OCT242023-OCT26BUILD内容

 タスク勤務表、列制約、シフト付きフェーズ制約で予定に、該当しないシフトがあったときのバグ修正を行いました。(大半の方には影響しないコーナケースです。)

2023年10月27日金曜日

Microsoft Certification Errorによりサブスク1週間の無料お試し期間無くしました

 突然に、

https://learn.microsoft.com/en-us/answers/questions/1390603/help-with-submission-error-10-1-4-6-app-quality-mi?source=docs

と同じで理由で、審査に落ちました。何のことかさっぱり分かりません。

問い合わせてみると、


Thank you for contacting us. The description claims that there is a week free trial. At launch, the product asks, "Do you like to purchase a subscription?". Selecting "No" closes the product. There is no option to choose a week free trial. Please either remove the free trial claim from the description or ensure that there is a free trial within the product and resubmit the product for certification.

Microsoft Store Team

<原因解析>

ソースは何も変えていません。ストア登録のところで、無料期間設定を7日にしていた筈なのに、なぜか、「なし」にされていました。再度 7日に設定し再申請したのですが、同じく、落ちました。原因は不明です。

<対策>
そこで、上で指示されているとおりに、「お試し期間なし」を表明することにしました。下記がその表示です。



英語版では、

<考察>
恐らく、Microsoftの何かが変わったのだと思います。恐らく、私以外にも被害者はいると思いますが、当面はこのスタイルとなります。これで審査はパスしました。(一応7日の設定はしたままなのでが、実際の挙動がどうなっているかは、簡単に確かめることが出来ないので分かりません。)

スケジュールナースは既に、多くの方々に使われており、その性能については疑いがない、という地位を確立しつつあると思いますので、実害はないと思います。

2023年10月26日木曜日

変則2交代一般化パターンの検討と最終実装案

<目的>

長日、ロング日勤を使用するパターンは、近年色々出ていますが、勤怠システムのサポート問題があります。様々な制約実装パターンに対して、最も実装が容易な形態について考察、考案しその普及を促すことを目的とします。

■列制約長入明数が同じならば、長入明パターンとするのが望ましい

例えば、長入明が(3,3,3)ならば、長入明パターンだけを用いて列数を揃えることはできる。

長入明しかないのであれば、前月との貸し借りでみれば、+-0であり、補償項(非番、半休)が必要ない。(今月という枠で見ると、長入り差は+-1発生する。これを勤怠システムの都合で、同じとすることは、解空間を狭めること、実装が重いこと、により推奨しない。勤務シフト上良いことは何もない。勤怠システムのために、看護師が余計に難しいシフトを強制されることは不条理)

より一般的な変則2交代では、このほかにパターン上のシフトを導入する。単長と、単入である。また遅番が必要な病棟もある。単長と単入は、長入明パターンにあてはまらない全ての長日と、入りシフトを表す。

■同じでない(例えば、長入明(4,3,3)あるいは、曜日により異なる)ならば、単長を導入する

列数が全て同じであれば、長入明パターンだけで実現できるが、そうでない場合は、必要な列数を過不足なく実現するには、単長の導入が必須となる。

単長に関しては、1.5Dayが必要となり、就業日数の増加に対する補償が必要とも考えられる。同値制約にこれを月内で自動補償するやり方、単長数=2*非番、も案としてはあるが、全スタッフに適用するにはソルバ負荷が重過ぎるので採用しない

そこで、非番、半休に関しての補償は、月累計にて、希望非番数、希望半休数という制約で、月毎に行うものとする。具体的には、非番数をスタッフプロパティシートに記載し、累計結果を見ながら適宜、補償を行う。

■単入の発生箇所

単入は、就業日数の減少を生むので、勤怠システムでも補償がしにくく発生自体をなるべく避けるべきと考える。

単入が発生するのは、次である

1)長日を行わないスタッフが少なくとも一人いる

2)休入を予定に入れてくるスタッフ

3)長遅入明パターンが一人でもいる


<単長が定常的に発生する職場>

単長が定常シフトとして存在する職場では、単長により列を揃えることは障害とならない。

<単長が定常的に発生しない職場>


長入明しかないパターンの職場では、列を揃えるため、他のスタッフに単長が必要となる。つまり、あるスタッフの単入を実現するために、単長が他のスタッフで必須となる。上を認めるか?禁止とするか?、で単入が必要かどうかが決まる。

いずれにせよ、単入に関しては、勤怠システムのサポートが必須となる。

設計例

      )2)可。3)禁止

   全夜勤スタッフが単長サポート。 ただし  単長数<=2

         列制約が長日数==入り数の場合、制約最終日の単長数は0にソフト制約する  

        単入は、自動アサインしない 

        (長日がないスタッフは、予定入力で、シフト集合[でない]を用いて夜勤可能候補日を指定する。)

   半休は、自動アサインしない

        非番数は、スタッフプロパティシート管理(繰越計算による指定)

     遅番3回連続禁止、遅番の後は、遅番または休みとする

このシステムでは、長入明の列数が同じであれば、パターンも基本、長入明だけになる。単長、単入も各スタッフは、アサイン可能であっても自然にそうなる。単入は、自動アサインにしないので、予定入力されたときだけ発生する。単入がなければ、単長があっても列を揃えることは出来ないので、自然に長入明だけになる。但し、制約最終日だけは、自然にそうはならないので、ソフト制約する。

長入明が揃わない例えば、(4,3,3)では、単長が1日一個生成されることによる。また、長入明を乱す上記1)2)3)の入力も可能とすることも可能とする実装にすることも可能ではあるが、単入りは、自動アサインしないので、余計に単入、単長が生成されることを抑制する効果がある。

単長と単入は、勤怠システムでのサポートが必要となるが、シフトとして区別可能で計数は容易である。(単にそのシフト数を計数すればよい。)

以上の実装と各種仕様への変更の仕方を示したプロジェクトの公開を行う予定。




      



3)に関しては、他のスタッフでの補償が必須となり影響度が大きいことから禁止とすべきと考える。





2023年10月25日水曜日

老健施設 日勤者数 風呂日3人それ以外2人

 まずは、風呂日集合を作ります。2F,3F,4Fで風呂日が違います。


後は、列制約で、日勤者数をそれぞれ指定すればよいだけです。


2023年10月23日月曜日

老健施設 夜勤者の階が被らない

 2F,3F,4Fというグループ属性を生成します。




各スタッフに階を設定します。


列制約でMax=1に設定します。


2023年10月22日日曜日

自動割り当てなしの挙動

 シフト自動割り当てなしは、ちょっと曲者で整理してみました。(OCT18/192023 BUILD版以降)

A■予定入力なし

自動割り当てのチェックがされていないシフトは、決して割り当てされることはありません。つまり、割り当てされるのは、自動割り当てチェックがされたシフトのみが可能性としてあります。

B■ハード予定入力 シフトの場合

そのシフトが自動割り当りあてのチェックの如何に関係なくそのシフトが割り当てられます。

C■ハード予定入力 シフト集合「または」の場合

自動割り当てチェックがないシフトが含まれる場合、そのシフトは割り当てられません。割り当てられるのは、シフト集合内の自動割り当てチェックされているシフトのみが可能性として、割り当てられます。

D■ハード予定入力 シフト集合「でない」の場合

そのシフトが自動割り当りあてのチェックの如何に関係なく集合演算結果のみにより、そのシフトが割り当てられます。

E■ソフト予定入力 シフトの場合

そのシフトが、自動割り当てされている場合、そのシフトとその他自動割り当てされたシフトが可能性として、割り当てられます。

F■ソフト予定入力 シフト集合の場合

予定入力なしと同じ挙動になります。自動割り当てされたシフトのみが可能性として、割り当てられます。

要するに、自動割り当てなしにされていて、シフト集合の場合が、要注意ということになります。特に、ハード制約「または」、と 「でない」が違います。


 例えば、下の予定ラベル日入は、日勤または、入りシフトですが、日勤は、自動割り当てなしされません。行制約によって入連続は禁止ですからラベル部日入には、入れるものがなくなるので、ハードエラーとなります。



それに対して、「でない」での予定集合夜1は、集合演算上、日勤または、明けが残ります。各々行制約禁止により、一つだけが残ります。

このどちらも自動割り当てなしではありますが、ルールDにより、各々明け、日が必然の結果として割り当てられます。



2023年10月21日土曜日

ペア禁止の一般化スタッフプロパティシート

 ペア禁止を一般的に行いたい場合のスタッフプロパティシートによる記述の仕方です。

下のようにペア禁止にしたいスタッフの属性項目を追加しています。

ペア禁止にする組が存在しなければ、このままで結構です。



ペア禁止にしたい組が出てきたとします。ペア禁止1~3から選び禁止したいペアの組を指定します。 



指定した状態です。

実装は、列制約で、同じグループのスタッフ数が最大1にしているだけです。

スタッフが退職等でいなくなったり新人が加わったりで、月々で色々な変化があるのが常ですが、この方式であれば、スタッフプロパティシートのみをメンテすればよいので、面倒なことはありません。お勧めです。


2023年10月20日金曜日

変則2交代 長遅入明は、避けた方がよい

変則2交代においては、長入明けパターンが基本です。

 長入明

 長入明

  長入明

この他に遅番が必要な場合、遅休一択をお勧めします。長遅入明パターンは避けたほうがよいでしょう。

通常パターンだけなら、綺麗に縦列の長入明遅の数を揃えることは容易です。



しかし、長遅入明パターンの人が一人でもいると、縦の数を揃えるのは、そのパターンだけでは不能です。



他のスタッフ、少なくとも3人にそれ以外のパターンを強いる必要があります。
確かに、長遅入明は、それだけを見ると遅専用休みが必要ないので、得したような気分になるのですが、縦列の数を揃えるのが容易ではなく、却って難しい勤務表となってしまいます。

結論として、長遅入明は、避けた方がよい、認めないというのが吉です。






2023年10月19日木曜日

OCT18/OCT19BUILDリリース

 未だ、マイクロソフトのcertificationが通っていないので、確実ではないのですが、恐らく月末までには、アップデートされるものと思われます。

今回のアップデート内容は、次の通りです。

1)ウィンドゥズの設定で、ツールストリップサイズ追加

シフトの数が多いプロジェクトでは、ラベル右端の青部をクリックすることで、ツールストリップオーバフローと呼ばれレイアウトで下のように表示することが出来ます。

しかしながら、極端にシフト数が多いプロジェクト(100を超える)では、全てを表示しきれない問題がありました。上記レイアウトを変更出来ればよかったのですが、変更出来るようなC#ライブラリになっておらず断念しました。苦肉の策として、ラベルの大きさを変更することにしました。下記の項目を追加しました。


このサイズを小さくするとラベルのサイズが小さくなり、より多くのラベルを表示することが出来ます。(見難くはなりますが、操作できないよりはまし)

2)ソフト予定制約のシフト自動割り当て設定がチェックされていないシフトの挙動を修正

シフト自動割り当てがチェックされていないと、ソフト化されたときにそのシフトが無視される問題を修正しました。

3)解画面の左ウィンドウのスクロール量が0でない問題の修正

Augビルドで、1になっていたのを0に修正しました。

4)スタッフ毎のシフト フィルタ、変更が直ぐに反映されない問題の修正

5)行制約表示

チェックマークが付いていない状態の行制約で、最大最小制約がInvalid時の赤マーク表示を修正

6)スタッフ毎のシフト・タスクの右クリックメニューにセットを追加


2023年10月13日金曜日

様々な変則2交代パターンの評価

 パターンとしては、3種類+同値カウントの制約有無2種類の計5種類試しています。

インスタンスとしては、ICUで、約70人のスタッフです。長入明、各10人の確保が必要です。

インスタンスAは、長入明を一塊とするパターンで、最も基本的なものです。

このパターンに対して、長日数==入り数制約を入れ込んだのが、Bです。厳密解は、22で変っていないのにも拘わらず、大きく劣化しています。この原因は、解空間の減少および、同値カウントの持つ重い負荷による分が効いていると思います。いずれにせよ、同値カウントは、このような劣化もたらす可能性が強く、勤怠システムで、このような制約がないことを祈るのみです。

Cは、長入明け塊に、長日、入りという単独日を追加したものです。一見、これにより、LBが下がることが期待されたのですが、厳密解(AL4による結果)を見る限りこれによる減少はありません。ほぼ、Aと同じ性能ということが出来るでしょう。

Dは、Cに対して、さらに非番、半休という休み系のシフトを追加したものです。これによりLBが下がり、実際、UBも下がっています。

Eは、Dに対して
単長数=2*非番数+半休数
という制約を付加したものです。LB値は、Dと同じですが、UB値は、劣化し、求解時間も2倍程度となっています。

以上の結果より、
1)同値制約は、重い。求解時間は、2倍近くとなり、UB値も劣化しています。
2)単長、単入り追加によって、期待されたLB値向上は見られない。
3)非番と半休数による長日端数分の補償は、Bに比べれば、劣化は少ないが、システムが複雑になった結果、求解時間が2倍程度となる。

以上の結果より、
■推奨パターンは、A となる。一ヶ月で切り取ると、長日と入りとの差は、+-1が発生するが、先月との貸し借りで見れば、0となり、面倒な時間補償計算が不要になる。
■長日数=入り数を入れることは、大きく求解時間と解品質を劣化させる可能性があり避けるべきである。
■長日補償の方法としてEの方法があるが、可能なスタッフは、パターンAを採用するなどして、システム負荷を小さくすることが、求解時間改善につながる。


AL4による改善(Ryzen9950) E:
Default:660sec  
同値カウントをハード制約化 147sec 
半休項のみを全クリア 142sec
半休非番項を全クリア 121sec

AL4では、ソフト制約をハード制約化することが大きく改善する。
Default:660sec  LB=UB=22
同値カウントをハード制約化 147sec LB=UB=22
公級数をハード制約化 143sec
5連勤務の後の2連休をハード制約化 115sec
入り回数をハード制約化 116sec
=> 半休非番項を全クリア(パターンA) 87sec
効果の大きい順:
同値カウント>パターンの長いソフト制約>かウント数の大きい基数制約

パターンAでの比較
AL4:UB=22 87sec
AL1:UB=27 144sec (UB向上の効果もある)







2023年10月12日木曜日

二人の新人について1人の指導者

 新人数 指導者数

-------------------

0     0

2     1

4     2

6     3

という関係性を記述したいときは、リニアペア制約で記述します。

ただし、上記仕様では、新人が奇数のときの取り扱いが明記されていません。

そこで、二つの場合について考えます。

一つ目は、Aを新人、Bを指導者としたとき

A<=2*B

です。Aが1人のとき、Bは、1人以上となります。Bが2人のとき、Bは、1人以上となります。(予定をソフト制約にして最小のBが出るようにしています。)

これに対して、Aが1人のとき、Bは、0人でもよい。Aが2人なら、Bは、1人以上としたい、というときの記述が次になります。






2023年10月11日水曜日

応援勤務

 一般病棟のスタッフが、外来や、救急外来に応援に行くことはよくあります。その際、自職場はそのままに、追加で応援先を設定できるようにした方がメンテナンス性が良くなることは言うまでもありません。応援先でも、日勤や、遅番というシフトが同じであれば、遅番⇒早番禁止等もそのまま有効に働きます。

ここでは、一般外来と、救急外来の二つの応援先を考えます。

まずは、応援先であり得るシフトについて、フェーズを記述します。

次に応援先をタスクで指定します。外来と救急外来を指定しています。この際、次のようにNoTaskVarを使い、チェックを行います。自職場にいるときは、NoTaskVarがActiveになります。

タスク予定で、応援先の応援日にタスクを指定します。


解です。遅番について救急外来がついています。

これは、特別の日の設定で、遅番用の日と日勤用の日を分けることによって実現しています。


また、応援者は、スキルが求められます。次のように指定します。


このようにすると、自職場のシフトは全くいじらずに、追加だけの記述で済ますことが出来ます。メンテナンス性が良いことがお勧めポイントです。



2023年10月10日火曜日

複雑なクリニカルコーチ制約

          1年目の夜勤は

  ■同じチームに夜勤要員が2名いる

  ■かつリーダーレベルが1名いる

■かつ、CC(クリニカルコーチ)がいる

を実装してみます。これらは、ANDなので、独立して実装すればよいです。また、

同じチームは、1年目のチームがAなら、Aチームとすればよいです。

■1年目(Aチーム)が夜勤ならば、Aチームの夜勤要員が2名以上は、

1年目をA,Aチームの夜勤要員をBとすると、

2*A<=B とすれば、よいです。Aが0のとき、0<=Bで常に成立、Aが1のとき

2<=B となり、B2名が強制されます。

■かつリーダーレベルが1名いる

A<=B=Σリーダレベルシフト和

■かつクリニカルコーチがいる

A<=B(クリニカルコーチ)

となります。





2023年10月9日月曜日

会議の実装変更

 会議の実装を変更しました。従来は、会議というシフトに対して参加者全員が会議シフトとしていたのですが、看護師長のみに変更しました。

というのは、

1)看護師長は、日勤のみで、日勤カウントされない。

2)召集スタッフは、副看護師長や、チームリーダ、クリニカルコーチ等、多数の全員が日勤とするのは、難しい。長日も含めたシフトとしたい。

という背景があります。単純に会議というシフトを全員に割り振ると、2)の対応が難しくなってしまいます。

そこで、次のように、看護師長をA,看護師長を除いた参加者集合をBとして、AならばBを実装します。AならばBの数理表現は、A<=Bです。


こうすると、看護師長のみに会議シフトとなります。その他の人は、通常のシフトとなりますが、看護師長が会議なら参加者全員が日勤、もしくは長日として解空間の減少を最小にします。

BFULLは、B集合の人数を指します。これにしておけば、会議参加者に変更が生じたとしても、この制約をメンテする必要はありません。(AFULLも同様です。)

A==Bでないことに注意してください。A==Bだと、BならばAケース、すなわち、たまたま召集スタッフが全員日勤のとき看護師長に会議が意図せずに付いてしまいます。会議数は、月に一回だけという制約を課しますが、これと矛盾する可能性が高くなります。


2023年10月8日日曜日

夜勤3名以下なら 男性スタッフ1名以下

 

このように複雑なペア制約は、AL3/4ではサポートしていません。しかし、リニアペア制約では、アルゴリズムによらず記述可能です。

まず、仕様を整理します。夜勤数2名以下と5名以上は別仕様によりありえません。すると、下のように、夜勤4名のときの規定がないことに気付きます。

夜勤 男性

-------------

1    x

2    x

3    <=1

4    -

二つの可能性があります。一つ目は、夜勤4名時も男性1名以下というものです。

夜勤 男性

-------------

3    <=1

4    <=1 

夜勤 男性

-------------

3    <=1

4    <=1 

二つ目は、夜勤4名時は、男性2名以下にする制約です。

夜勤 男性

-------------

3    <=1

4    <=2

リニア制約では、各々、次式となります。

A>=3B 

A>=3B-2

上式が、上表を満足することを実際に確認しましょう。

A3人、B1人は、3>=3 、3>=3-2=>3>=1で成立

A3人、B2人は、3>=6不成立 、3>=3*2-2で不成立

A4人、B2人は、 3>=4不成立、4>=3*2-2で成立

となります。

実装は、定式をそのまま記述します。



2023年10月6日金曜日

リニアペア制約の評価

 残念ながら効果は認められませんでした。

一般に数理ソルバにとって、ANDやORというオペレーションより、リニア制約、の方が簡単です。その発想で、リニアペア制約化すれば、AならばBも上手く行くのでは?という期待があったのですが、残念ながら、分岐限定による整数化で効果は少しだけあるものの、「目に見える効果としてはない」 という結果でした。

<リニアペア制約実装は無駄ではない>

では、無駄だったかというと、決してそうではなく、現場で、重宝して早速に使っています。

<数理ソルバでの求解困難インスタンスの原因>

依然として、全てではありませんが、ペア制約AならばBが大きな割合を占めていることは間違いなさそうです。リニアペア表現でも上手く行かないということは、恐らく大きな係数にその原因がありそうです。

通常の列制約ならば、

ΣA[i]=[Min:Max]

です。つまり係数は全て1で単純な加算和が[Min:Max]の範囲内というのが一般形式です。

それに対して、ペア制約は、

ΣACoff[i]*A[i]=[Min:Max]

となる部分が異なります。例えば、会議の制約では、おおきな係数の制約となります。

現状、この部分を打開する手立てを見つけることができません。厳密解を求めたい場合は、次のような手順を取ります。

1)会議等制約含んだ全体を、AL1で解く。

2)1)で求めた会議日を予定としてハード制約化する

3)数理ソルバ(AL4)で解く

1)の時点で、厳密解ではなくなっているのですが、高々31日のBranchを試しても同じです。これで、今まで求められなかった厳密解が出てくるかもしれません。








2023年10月5日木曜日

OCT03/04_2023BUILD配信中

 OCT03/04_2023ビルド版が配信中です。

追加内容は、

1)スタッフ毎のシフト・タスクにフィルタ追加

https://schedule-nurse.blogspot.com/2023/10/blog-post_2.html

2)リニアペア制約

https://schedule-nurse.blogspot.com/2023/10/blog-post_3.html

3)同値カウントに不等式制約とオフセットを追加

https://schedule-nurse.blogspot.com/2023/10/blog-post_4.html

です。


ビルドは、通常、月末を狙っています。勤務表作成は、第2週位がピークのようであり、月末から月初めが、一番閑散となります。今回は、ソルバとGUIの検証に手間取り少し遅れてしまいました。

今後一週間程度で行き渡ると思います。マニュアル改定は、10月11日以降に行う予定です。

<お知らせ>

11月6日~12日までサポートを休止します。



2023年10月4日水曜日

同数カウントに不等式追加

 整数カウントに不等式、同数カウントにオフセットを追加しました。



ΣACoff*A[i] 演算子 ΣBCoff*B[i] +offset

となります。係数は、シフト表のカウント値となります。2番目の画像の制約は、長日の数は入り数に対して+0-1以内であることを制約します。+側にはみ出した長日部分(4h)は、半休(4h)または、非番(8h)により補償されるという制約です。

長日数<=2*非番数+1*半休数+入り数

長日数>=入り数ー1

同数制約は、ソルバ上重い制約であり、かつ解空間を狭めるので、その使用は極力避ける設計としています。具体的には、長入明シーケンスのみのグループとそれ以外に分け、それ以外グループでのみ、上式を適用した実装としています。


2023年10月3日火曜日

リニアペア制約追加

 リニアペア制約による記述


AならばBによる記述との対比


演算子は、==、>=、<=の3種類、オフセットは、+-1、+-2...をサポートしています。

係数は、A用とB用で独立してあり、各々ACoff ,BCoffとすると

ΣACoff*A[i] 演算子 ΣBCoff*B[i] +offset

となるように制約します。

用途は、数理的表現が必要な場合用です。殆ど場合、上のように、現状のペア制約で事足りますが、数理的表現の方が、簡潔に記述できる場合があります。

例えば、新人二人につき一人の指導者がつく制約を考えます。

新人数 指導者数

-------------------

0     0

1    禁止

2             1

3           禁止

4    2

.....

このような場合、論理的制約では、多数の制約記述が必要となります。数理的記述が可能ならば、Aを新人、Bを指導者として

ΣA[i]==2*B[i]

という風に、一つの制約で、記述できます。

どちらかというと、数理ソルバーでは、Nativeな記述ですが、論理的ソルバーでは、苦手な記述となります。

2023年10月2日月曜日

スタッフ毎のシフトタスク設定でフィルタを追加

 フィルタには、なっていませんが、フィルタという名前にしてしまいました。

新しいスタイルでは、スタッフ毎のシフト・タスクのチェックを割りに頻繁に変えることがあるかもしれません。そうなると、各スタッフのプロパティを参照したくなるので、追加しました。(未だリリースしていません。今月10日頃の配信となります。)


2023年10月1日日曜日

変則2交代の希望シフト統計を基に実装に関する一考察

次のような体感統計となりました。

1位:休み

2位:明休

3位:入(休入、日入)

4位:日

1位の休みは、当然として、意外に多いのが、明けの後の休み、これは、明けの後の休みが当然ではない、の裏返しではないでしょうか?

3位の入りは、休入、日入まで、指定したものがあります。これは、長入明パターンを阻害します。

「明けの後の2連休を出来る限り多く」、というのが多くの職場で要求されるパターンですが、それに関して、最も効率がよいのは、長入明パターンだけで構成される職場です。

仮に、入り回数が4回以下という条件であれば、

長入明休休..長入明休休..長入明休休..長入明休休

という状態となり、4週8休の条件下で、全ての明けを2連休とできる可能性が高まります。

入り回数が5回以上なら、その条件は物理的に満たせません。

理想的には、

■入り回数4回以下

■全員、長入明パターンのみ

■勤怠システムは、長入り差を+-1まで許容する

であることです。長入明パターンのみで構成されれば、長入差は、自動的に+-1以内となり、重い==制約を使わなくてもよくなります。

しかし、現実には、

■入り回数5回以上がある。(職場によっては、殆ど6回のところもある)

■上記のように個人の希望により、長入明パターンだけには、できない。

■勤怠システムのなかには、長入差は、+-0を強制される場合がある

等により、上記理想条件をキープ出来ずに、2連休達成は、物理的に不能な場合が存在します。また、長入パターンだけに出来なければ、長勤務者数、入り勤務者数を揃えるために、また、新たな勤務、単独長(長休),遅出 等が必要になってきます。そうすると、長入差を埋めるための、非番や、半休といったものが必要となり、複雑な条件を達成するため、求解性能の劣化が懸念されます。

上記希望シフトに着目します。それは、長日希望が一つもないことです。数ある希望シフトで、長日が一つもないということは、出来れば長日はやりたくない、ということが伺えます。それに対して、入り希望はあり、長入明パターンを阻害する希望シフトが入り込むことがありえます。

以上の知見から、次のような二つのグループに分ける発想を得ました。

■A 長入明パターンだけのグループ

■B  長だけ、単長あり、休入、日入り等、イレギュラーパターンを含むグループ

Aグループだけで、見れば、長入明勤務者数列は、常に自動的に一緒になります。また、長入差は、自動的に各スタッフで+-1を保証できます。

Bグループだけで見ると、長入明勤務者数は、一緒になりません、また、長入差も存在することになります。長だけの人は、半休もしくは非番とセットにする必要があります。Aグループの長入明勤務者数は、常に一緒であるので、Bグループの長入明勤務者数も常に一緒であることが必要です。つまり、Aグループ、Bグループ単位で長入明勤務者数が一緒である必要があります。具体的には、Bグループに長だけ行う人だけが場合は、長入明勤務者数一緒列が常に成立しないので、長を行わないことがあるスタッフを組み入れる必要があります。(月毎にグループ人員を入れ替える案もあります。)

このようにする背景は、Aグループが大半とし、少数のBグループとすることで、煩雑な部分を限定することができ、結果として、処理速度の向上、結果的に、明け後2連休の達成度を上げることにつながる、ということがあります。

本来は、全スタッフをBグループとしても、同じ求解品質となることが理想ですが、残念ながらそうではありません。Aグループは、シンプルパターンのみ構成され、一見自由度がないように見えますが、行列の要件に対して達成しやすいパターンであるとも言えます。解空間は減少しているように思えますが、真の解に近いパターンのみが生き残り易いとも考えられます。

それに対して、Bグループは、煩雑なシフトに対して、行列要件を満たすことが必要となります。特に==処理は、AL1にとって重い処理となります。

Bグループでは、Bグループパターン用の特入りを追加します。(Aグループ内では、特入りは、不可です。)

これは、日特入、休特入を可能にする入りです。希望シフトでこれを記入することが可能となります。また、Bグループでは、各スタッフ、

■長日数<=2*非番数+半休+特入り

■長日数>=特入り-1

に制約します。これにより、長の余り数は+0-1に制約されます。

この処理が重いのは、多数のシフトがこの等式に拘わっていて、なおかつ、>=と<=により両サイドから制約されることにあります。なので、Bグループはなるべく小さく、しかし、十分にBグループ内で、長入明勤務者数列が一緒に出来るようなスタッフ数としてください。

通常は、ソルバの性質にユーザは深く立ち入る必要はないのですが、こと長日数差が制約として必要となる場合は、以上のような観点での制約設計とすることが、皆の幸せにつながる(希望の通り易さ)と思います。

なお、長日数差が勤怠システムの中で制約の必要なければ、非番、半休は必要ないし、==処理も不要となるので、上記のような面倒なことは、必要ありません。