2026年3月18日水曜日

Q. 表示用シフト集合の作り方

 Q.

1.シフト集合にシフト集合名「宿直カウント用」、ラベル「宿直集合」、演算子「または」、

シフト名「宿直」、「30分遅・宿直(終了日が休日)」、「60分遅・宿直(終了日が休日)」

及び「30分遅・30分早上がり宿直(終了日が平日)」を追加する。


2.行制約グループ1の宿直回数の「宿直」を「宿直集合」に変更する。

とすれば、ひょっとしたらうまくいくのでは?と思いましたが、2の設定ができませんでした。


Ans.

シフト集合の要素は、「シフト」である必要があります。シフト集合の要素をシフトシフト集合とすることは出来ません。エントリしたいシフト集合のシフトに分解してエントリしてください。


演算子は、または(非自動含む)を選択してください。(自動割り当てされないシフトも含むので。)

制約は、≧0とすることで、実質制約することはしません。表示Only目的での制約の書き方になります。


以上です。最後に動作を確認して終了です。



2026年3月17日火曜日

Q. カウント表示がおかしいのでは?

Q. 2内Aに宿直が1回割り当てられていますが、2内Aの宿直回数はゼロ回になってしまっています。

Ans.

当該部を拡大してみると、宿直60分遅となっており、同じ青色の常勤医師の宿直とは異なるラベルになっています。


実際、にシフト定義を見ると、シフト宿直とは異なり、派遣医師用の特殊シフト(自動割り当てされない、予定入力専用シフト)であることが分かります。

実際の制約は、宿直のみに作用しています。

結論として、宿直回数0になっているのは正しい、です。

<考察>
同じ青色でしたので、誤解を招く結果となりました。対策として、

1)宿直60分等の色を少し変える
2)例えば、総合宿直のような合成集合シフトを作って、≧0で制約する

等が考えられます。



2026年3月16日月曜日

Q. アルゴリズム1は、過去に比べてどのくらい良くなってますか?また、今後の見通しについては?

 Ans. 

最新のSAT Competitionを推移を見ると、確かに僅かずつではありますが、性能向上が認められます。が、必ずしも、ナーススケジューリング問題用に向上している訳ではありません。むしろ、1世代前の方が良い場合もありえます、というよりもその場合の方が多いです。

過去との比較、スケジュールナース1/2との明確な比較結果はありませんが、体感できるくらいの性能向上は出来ていると思います。

現在リリース中のソルバは、1世代前のCryptiminisatのあるバージョンを修正したものを使用しています。最近、最新ソルバに置き換えたものを比較してみましが、全く最新ソルバは、現行リリース版に勝てませんでした。従い、現在リリース中のものが、アルゴリズム1としては、過去現在において最高性能であることの裏付けが取れました。

推測になりますが、アカデミックな関心がSAT competitionで優勝することに向いていて、実務的な性能向上から離れてしまっていることに原因があるような気がしています。具体的には、incremental solvingに関する向上が殆どない、ことに起因します。

今後については、アルゴリズム1単独での性能アップはあまりなく、他の種類のソルバとの連携において力を発揮する、と考えています。そのための統合化作業を現在進行中です。

2026年3月15日日曜日

MDDサイズは、Kに比例する

幅0の係数制約について考えてみます。幅0とは、

ΣCoeff[i]*X[i]≦K、ΣCoeff[i]*X[i]≧K

と、最大・と最小がKに一致した問題です。

K=0のMDDグラフです。幅1であることが分かります。選択肢がありません。

X[i]=0 ∀i

であることを要求しているので当然です。



K=1のMDDグラフです。0または1の2種選択肢があります。




K=4のMDDグラフです。定常状態では、5つの選択肢(幅)となります。




K=10のMDDグラフです



一般にイメージされがちなのは、最大・最小が同じなら、K=1でも、K=10でも同じ解空間では?と思いがちですが、実態は、全く異なり、ほぼKに比例するということです。

幅0が効くのは、最後だけであって、そこから離れれば離れる程、幅は広くなり最終的にK幅となります。ざっくり、問題の難易度は、Kに比例するということです。


これを勤務表作成問題に当てはめると、

■制約日数が長ければ長い程難しくなる

■スタッフ人数が多ければ多いほど難しくなる

ということが理解されると思います。

例えば、夜勤人数1名(1名以上1名以下)と夜勤人数10名(10名以上10名以下)では、夜勤人数10名の方が10倍程度、上で見たようにノード変数数が増えるので、それだけ解きにくくなる、ということです。月数が12カ月になれば、さらにノード数は、12倍となります。全体としては、120倍難しくなります。これが、combinatorial explosion組み合わせ爆発の源です。

ナーススケジューリング問題は、NP困難であることが証明された問題であり、問題が大規模になれば、やがてReasonableな時間内に解くことは出来くなる、ことが分かっています。しかし、数学が証明しているのは、それだけであり、この規模なら解けない、と断じている訳ではありません。私達研究者は、神様が決めた限界を突破することはできませんが、解ける限界範囲を出来る限り伸ばそう!と日々努力しているということです。


2026年3月14日土曜日

Q.入力ラベルの配置を変えたい

 Q.入力ラベルを入れ替えたい。


Ans.まず、ラベルの順番について説明します。次のような順番に固定されており、順番を変えることは出来ません。

  シフト名→ 別名1→ 別名2..

     ↓

  シフト名→ 別名1→ 別名2..

         .....

         シフト集合名

     ↓

         シフト集合名

         .....

方策1) シフト別名で使っていないものは、削除します。結果的に右のラベル群はスライドして上がってきます。

方策2) シフト別名をシフト集合で定義し直します。 シフト集合内での順番は、変えることが出来ます。不要なものは、後ろに配置することで、結果的に右のラベル群はスライドします。

方策3) キーボードのbinding使用

  https://schedule-nurse.blogspot.com/2023/11/blog-post.htm
 

  頻繁に使用するラベル順に定義します。慣れれば圧倒的に速いです。

  なお、名前は、Excel等でと短冊シートを作ってキーボード上部に貼っておくと、慣れるまでの間重宝します。




2026年3月13日金曜日

ReducedCostとは?

 HIGHSソルバで、LPを解くと、4つのSolutionが出てきます。solutionというと、通常は、ColSolutionになります。これは、SAT解を得たときの解に相当します。Dualは、双対と訳されます。双対とは、

目的関数 ⇔ 制約

の間にある数理的な関係を指しています。

制約を固定して、目的関数を最初にする(主問題)のと、

目的関数を固定して、制約を最大化(双対問題)する

のは、ある種の対称性があります。これは、Linear System全てについて当てはまり、主問題があれば、双対問題も自動的に定まります。これは、OR特有の概念です。双対定理は、


■Col Solution ⇒x(i)

■Dual Solution  ⇒y(i)

■Row Activity

■Reduced Cost  ⇒r(i)

です。数理ソルバで特に重要なのは、ReducedCostです。

Reduced Costは、

rj=cj-ajTy

で計算出来ます。

ciは、xについて目的関数値の係数です。yは、dual値、ajは、システムマトリクスの係数です。ReducedCostは、x(i)に付随する量なので、x(i)サイズ分値を持ちます。x(i)に関して 目的関数の悪化(改善)具合を表していると考えられます。多くのMIPソルバ内で、PuedoCost(疑似コスト)の初期値としても使われています。

スケジュールナースの数理ソルバ内では、このReducedCostを駆使しています。


2026年3月12日木曜日

Daul==0でスラックに余裕があるとき、その行は削除してよいか?

 インスタンス24は、制約が重すぎてLPソルバが遅いので、一時的に削除できないかを検討しました。

結論的には、上記条件でも以下の議論の通り削除することは出来ません。それ以前に、オリジナルLPで、お目当ての行群中、DUAL=0の行が存在しなかったので、それも意味がなく、削除不能という結論です。


❗ DUAL値 = 0 でも制約を削除してはいけない理由

DUAL値が 0 というのは、**「最適解においてその制約が binding ではない」**というだけです。

binding ではない → 余裕がある

余裕がある → 緩めても目的関数は改善しない

しかし → 削除すると可行領域が広がり、別の解が出てしまう可能性がある

つまり、


制約は「最適解を規定する」だけでなく、「不適切な解を排除する」役割も持つため、

DUAL値だけで削除判断をするのは危険です。


🧭 では、どんなときに削除してもよいのか?

以下の条件が揃うと、削除しても安全な場合があります。

1. 制約が常に冗長(redundant constraint)であると証明できる

例:

他の制約の線形結合で表せる、または常に他の制約により厳しく支配されている。

これは数学的に確認できる場合のみ。

2. 制約の右辺を大きくしても可行領域が変わらない

DUAL値 = 0 の制約には「許容範囲(allowable increase/decrease)」があります。

allowable decrease が無限大

allowable increase が無限大

のように、右辺をどれだけ動かしても可行領域が変わらない場合は、削除しても影響がありません。

3. 制約が論理的に不要であることが問題構造から明らか

例:

上限 100 の制約と上限 80 の制約が両方ある → 上限 100 は不要

x ≥ 0 と x ≥ -5 → x ≥ -5 は不要