は、GenerativeAIをほぼそのまま張り付けた文章。
こちらは、使わないでいつものアシストで修正した文章。
https://schedule-nurse.blogspot.com/2024/01/relationship-between-level-and-weight.html
違いは歴然です。CHATGPI3ベースらしいですが、内容を理解して分かりやすくしている点が素晴らしいです。
は、GenerativeAIをほぼそのまま張り付けた文章。
こちらは、使わないでいつものアシストで修正した文章。
https://schedule-nurse.blogspot.com/2024/01/relationship-between-level-and-weight.html
違いは歴然です。CHATGPI3ベースらしいですが、内容を理解して分かりやすくしている点が素晴らしいです。
マクロは、整数だけを置換するものでしたが、浮動小数もサポートすることにしました。
具体的には、時間制約の値に対して作用します。
適用は、2月第2週です。
ソフトシフト集合仕様変更
https://schedule-nurse.blogspot.com/2024/01/blog-post_28.html
シフト集合要素のSanityチェック追加
マクロTextBox WordWrap禁止・最大容量1MB→10MB
ソフトシフト集合の仕様をシンプルにし、オペレータに関係なく、基本的に全集合としました。唯一、スタッフ毎のシフト設定は、ハード制約なので、チェックを外すと除外されますが、それ以外は、全集合となります。
がアナウンスされました。現在のHighsの内点法ソルバは、マルチスレッド化されていなくて、仕方なく、自作していましたが、これで、拙作ソルバは、お箱入りになると思います。楽しみです。
またEUのOR学会での最後にエジンバラ大学で、初のワークショップが開催される模様です。PhDは、無料とのこと。オンライン聴講は、(案内はないので)多分ないと思います。
No, it's not a bug.
Please see the link below for more details.
https://www.nurse-scheduling-software.com/constraints_faqs/chapter41/
サブスクリプション購入 (nurse-scheduling-software.com)
ストアにマイクロソフトアカウントにサインインしてから、操作するように変更しました。
また、ストアへの直接リンクを無くしました。
Intel UHD Graphics バグ対策
https://schedule-nurse.blogspot.com/2024/01/intel-uhd-graphics.html
マクロ説明ファイル作成改善
特定のGPUで、特定のRGBを持つラベルが黒くなる現象が報告されています。
NVIDIA系GPUでは、起こりません。IntelCPUが内蔵するGPUでのみ起きる模様です。具体的には、高画質のノートPCです。顧客の情報では、新しいPCでのみ発生するとのことです。私のNoteもIntel 系ですが、低解像度のためか、発生しません。これは、描画の問題であり見た目だけの問題です。内部の制約に影響はしません。
ある顧客から、指摘を頂き、当該機種系統のPCを新たに購入したところ、再現することができました。
原因解析:
ビットマップをライブラリ(syncfusion)に渡すところまでは、問題ありませんでした。(アプリ上では問題を発見できませんでした。)ライブラリ内部となるために、解析できませんでした。可能性としては、
以下の指摘です。
.net - WriteableBitmap.WritePixels not refreshing on some PCs - Stack Overflow
原因推定:
特定RGB範囲でのみ、観測されるので、恐らくは、intel uhd graphicsのバグだと思います。
対策:
ドライバーのupdateで回復する可能性が強いと思います。しかし、ドライバーのアップデートは、難しいでしょうから、対策することにしました。特定RGB範囲でのみ、不具合が観測されるので、特定RGB範囲は、近くの問題ない領域に避難することにしました。
リリース:
JAN242024
通常に比べ多くの日勤者を要する会議では、月初め・月終わりの数日間は避けた方がよいです。理由は、先月・次月の影響が出るからです。会議を意識して、例えば、先月から夜勤が入らないようにすれば、影響を最小にすることは出来ますが、中々そこまで気が廻らないのではないでしょうか?
Q.
Would you please be so kind as to explain me what the purpose of the
"weight" in the Solve tab ?
Is there any impact changing the integer value of it ?
I understand the "soft level" principle but the weight...
I may have missed this part somewhere in the documentation, sorry if it is
the case.
Kind regards,
Ans.
制約では、次のようになっています。
まずは、チェックマーク(✔)休集の意味です。
休集は、あらゆる休みの集合体です。チェックマークは、それに対して反対を取ることを意味します。集合で言うと補集合です。
つまり
✔休集=勤務
となります。勤務は、日勤かもしれないし、長日、入り、明け、研修..あらゆる休み以外のシフト全ての集合です。
上のパターンを解説します。7日のパターンですが、実は、これに包含される
制約があります。6連禁禁止です。
なので、上の6日目のパターンは、通常休みになります。その後7日目での勤務が、7日のパターン全体での勤務パターンになります。つまり、5連勤務の後休み、その後勤務というパターンです。制約は、パターン禁止ですから、
「5連勤務の後休み、その後勤務」というパターンの禁止
になります。ここで、既に6連勤務は、規制されていることに注意してください。7日パターンのみでは、6連勤務禁止にならないことに注意してください。
制約パターンの検証方法
弱いソフト予定で考え付くパターンの全てを書いてみて、目論見どおり動くかを見るとよいです。制約パターンの方が強ければ、弱い予定は、全て制約パターンに規制されます。目論みの「5連勤の後2連休」に当てはまらないパターンが解にあれば、制約設計のバグ、ということになります。なお、目的外の制約をオフにすると(求解時のチェックを外す)スピーディにデバッグすることが出来ます。
下記で、CCは、クリニカルコーチのリストですが、CCが存在しない場合は、エラーとなって、止まってしまいます。
import sc3 for person in a_1年目: list=[] for day in 今月: v=sc3.GetShiftVar(person,day,'ロング日勤') vc=sc3.GetShiftVar(CC[0],day,'ロング日勤') list.append(v&vc) s='1年目CCと長日_'+staffdef[person] sc3.AddSoft(sc3.SeqError(1,1,3,list),s,4)プログラムは、CCの存在を暗黙のうちに仮定していましたが、堅牢なプログラムならば、それをものともせず動き続けるはずです。次のように修正しました。CCが存在しない場合は、警告を出力します。
import sc3 for person in a_1年目: list=[] for day in 今月: v=sc3.GetShiftVar(person,day,'ロング日勤') try : vc=sc3.GetShiftVar(CC[0],day,'ロング日勤') list.append(v&vc) except: print("警告 CCがいません") s='1年目CCと長日_'+staffdef[person] if len(list)>=1: sc3.AddSoft(sc3.SeqError(1,1,3,list),s,4)
休日に、副看護師長が、日勤または長日>夜勤の順の優先度で、少なくとも一人は居て欲しい
これが実現できるところは、限られているかもしれませんが、
一応書いてみました
休日勤務は、休日にありえる勤務の全てです。こちらの制約の優先度は高くして、最悪、夜勤でもよいから居てほしいという、意味にします。マウスMiddleボタンで表示確認
https://schedule-nurse.blogspot.com/2024/01/middle.html
シフト・タスク Excel Import改善
https://schedule-nurse.blogspot.com/2024/01/excelimport.html
マクロの進化
https://schedule-nurse.blogspot.com/2024/01/blog-post_10.html
スプレッドシートの機能
https://schedule-nurse.blogspot.com/2024/01/blog-post_11.html
https://schedule-nurse.blogspot.com/2024/01/blog-post_12.html
マクロがどこで参照されているか?を調べる
https://schedule-nurse.blogspot.com/2024/01/blog-post_13.html
画像付き使用法説明用htmlの作成
https://schedule-nurse.blogspot.com/2024/01/html.html
リニアペアフェーズの拡張
https://schedule-nurse.blogspot.com/2024/01/blog-post_14.html
リニアペアフェーズ制約において、シフトA/シフトBをオプションとして追加しました。
オプションなので、なくても動作します。さらにAについては、タスクAもしくは、シフトAのどちらかが、Bについても、タスクBかシフトBのどちらかがあれば、よくなりました。
例えば、下のAタスクは、記載されていませんが、Aシフトは記述されています。Bについては、BタスクとBシフトの両方が記載されています。
記載されているということは、条件であり、ANDで結ばれることになります。これに対し、記載されてないことはDon't Careということであり、何であってもよい、ということになります。
この問題は、かなり高度な部類です。これ以上複雑なDay条件のときは、タスク予定上の予定テーブルによる記述の方がよいでしょう。
上の記述について解説します。上二つは、会議時に日勤者数最小を規制する制約です。副看護師長会議時の日勤者数を増やす記述です。具体的には、最小値を底上げする記述になります。
<最小値に条件を追加する>
A*Coff<=B*1+0
今、Aは、副看護師長会議時1、その他は、0とします。その他のときは、0ですから、0<=B 常に成立します。会議時は、
Coff<=B
となり、会議時は、Bシフト=日勤は、Coff人以上居ることを要求する記述になります。言い換えると、会議時以外は、何もせず、会議時は、日勤者数を規制する制約となります。この要領で、同じDay集合上に、いくつもの制約をオーバライドすることができます。これがMinに対する整数計画的記法となります。
<最大値に条件を追加する>
問題は、最大値です。
CoffA*A Operator ΣCoffB[i]*B[i]+offset
において、アクティブ0で条件が働くようにします。
通常時、Aは、1としてCoffA+Offset>=ΣCoffB[i]*B[i]
アクティブ時は、0としてOffset>=ΣCoffB[i]*B[i]
と作用させます。つまりOffsetは、Active時の最大値とすればよい訳です。ここで、
offset=-Offset
CoffAは、整数プログラミングの世界では、bigMという呼称が一般的です。
CoffA+Offsetがあり得る最大値以上すればにすれよく、CoffA=bigMがそのための定数です。数理ソルバー的には、一定以上であれば、問題ないのですが、2値ソルバー上では、大きすぎると問題ですので、必要以上に大きくしないようにします。
よって、次のようなマクロ記述になります。
BigMの計算方法
マークダウン言語(md)からhtmlを生成しています。病棟のPCは、ネットワークから遮断された状態が多いので、画像にしても外部参照ではなく、ローカルに持つのがよいでしょう。その際、複数のファイルをコピーするのが面倒という場合もあるのでhtml自身に画像を持たせています。こうすると、プロジェクトファイルがあれば、他は何もいりません。(プロジェクトファイルのコピーだけで済みます)
具体方法です。mdからhtmlを生成するのは、Typoraを使用していますが、何でもよいと思います。
画像のファイルは、Base64で変換したものを下記mdソース上の"..."
にコピペすればよいです。
<img src="data:image/png;base64,xxxxx”>
コンバータは、"md base64"で検索すると沢山でてきます。
下記は、Typora上の表示例です。
スケジュールナースで独自に実装している関数は、C(Day集合アドレス)、=C(グループ集合アドレス)だけです。それ以外の関数は、以下を参照してください。
Formula Support in Windows Forms Grid Control | Syncfusion
Cは、Countを指し、当該集合の要素をカウントします。
「今月土日」の数を数えて、それを公休数としています。
マクロは、単に数値の置き換えだけではなく、当該計算で必要な数を提供する機能を有しています。黄色の部分が、スプレッドシート機能を有する部分です。Excelライクな記法ですが、Excel互換ではなく独自のものです。詳細は、以下のAPIを参照ください。
Formula Support in Windows Forms Grid Control | Syncfusion
例えば、通常時平日最大日勤者数は、8です。この値は使用者が設定する値です。
しかし、制約上では、使いたい値は、マイナスした-8として記述したいという状況があります。ユーザ側では、-8にする理由が分からないし、細かい制約の事は気にしたくないので、単に8として値として設定したい訳です。そういう場合は、「式の値を適用」にチェックを入れて、「式の値」のところに式=-D4 としてやります。ユーザが8と設定したセルは、D4セルであり、そのマイナスの値をマクロの値として使う、という意味になります。
式の値を編集モードにすると、式編集になります。
マクロ機能を充実させます。設計意図は、
1)なるべく制約を見ないで設定できるようにする(メンテナンスの容易化)
2)意図しない、誤制約を防止する
3)設定の説明画面により、使い方の理解の容易化
です。外観は、以下のようになります。
説明画面
マークダウンで書いたものをTyporaでhtmlにしたものを左上のTextBoxに貼り付けています。再ロードすると当該プロジェクトフォルダーにプロジェクト名.htmlがファイル生成されます。それをC#webbrowserで右上に表示させています。WebView2も試したのですが、DLLがデバッグモードで作成されているために、審査キットで不合格となり断念しました。
ともあれ、プロジェクト作成者が、使用者に使用法を説明をするのは、ここを使えばよいと思います。
なお、説明用htmlファイルが既に作成済みの場合にはそれを「htmlファイル」で、ファイル指定します。Textボックスの中身は、全部クリアして設定ボタンを押すと、指定htmlファイルを指すようになります。
プロジェクトの全日数と同じである必要がありましたが、この制限がなくなり、制約表示開始日から、制約開始日の間のスタートであれば問題なく読めるようになります。1月15日の週のリリースになります。
次の予定で、プロジェクトの表示開始日は、26日です。Excelデータは、25日からありますが、25日のデータは無視されて26日より取り込まれます。
ある病棟での質問です。これについては、特定の月の特定の予定については、求解すれば、分かります。が、それ以外の、一般月の一般のシフト希望予定に対しては、答えをだせません、というのが回答になります。例えば、休み希望何個まで、という条件があれば、未だ検討の余地がありますが、無制限のシフト希望に対しては、無制限の組み合わせがあるので、これをハード予定とした場合、答えを出すことは出来ません。
一方、ブランク予定については、正確に必要人員を割り出すことは出来ます。ブランク予定とは、予定が全く入力されていない状態を指します。
全てのスタッフが一律に同じ夜勤回数でないのですが、要は、個々のスタッフが最大夜勤回数をこなしたときに供給できるコマ数は決まっています。具体的には、スタッフプロパティシートの最大夜勤回数をExcelで総計し、供給コマ数を求めます。(全てのスタッフが同じ最大夜勤数ではないし、夜勤しない人もいる)
一方必要な夜勤コマ数は、10人/Dayとすると、最大必要なコマ数は、10x31=310コマとなります。必要なコマ数310コマに対して上記コマ数が下回れば、絶対的な人数が不足していることになります。
310コマが物理限界なので、人員を削っていって、この値にどこまで肉薄できるか?がソルバの実力ということになります。実際は、綺麗に310コマに配置できる訳ではないことに注意してください。ブランク解の場合、ほぼ数コマ分以下となるのがスケジュールナースの実力です。通常、4~6コマ/人なので、言い換えれば、物理限界+1人分の人員と、無制限のソフト予定化が許されれば、必ず配置できることになります。なぜならば、無制限のソフト予定化が許されれば、究極的にはブランク予定とすることできるからです。
ここまでのまとめ
(1)物理必要コマ数に対し供給コマ数が下回れば、物理的に配置不能
(2)一般シフト予定にたいして、必要人員は見積もることができない
(3)ブランク予定については、見積もりが可能
実際は、無制限のソフト予定化ができないので、何がしかのプラスα人員が必要ということになります。それは、その職場の希望休み状況と不足事態に対するマージンの取り方によるので、実績を積み重ねて推定するのが現実的、ということではないでしょうか?
一般的には、物理コマ数に対して、5~7%程度を見るのがよくある人員設定です。3%以下だと、かなり無理がある状態、つまり人力で行うと、最大設定夜勤数に対してそれを超えるスタッフが散見される状態であると思います。