ペア設定で書きたくなりますが、A/B とも同じ集合(男)だと、動作しないと思います。
これは、ペア設定ではなく、
Σ男 <=1
と制約すれば、2名以上の男性が勤務することはありません。よって、スタッフプロパティで、性別を指定し、次のように記述します。
2020年2月13日木曜日
2020年2月12日水曜日
2020年2月10日月曜日
xbyakによる実装
Xbyakは、Intelのアセンブリ言語命令を実行時に生成するC++のライブラリです。
今の時代、LLVMがあるので、C++コードのJITコンパイルも可能になっており、その必要性は狭まってはいますが、Xbyakで記述した方が手軽な場合もあります。
例えば、IntelのMKL-DLLという深層学習用の高速化ライブラリがありますが、そのエンジンには、Xbyakが使われているそうです。
https://blog.cybozu.io/entry/2019/04/15/170000
またスパコンCPU aarch64(ARMの64ビットアークテクチャ)にも移植されているようです。
Xbyakの概要はこちら。
今回の使用目的は、機械・深層学習用ではなくて、AL4の高速化です。AL4は、数理的ソルバーですが、部分問題を解く必要があり、そのための新しいアイデアに対する実装に使用します。
コンパイル時定数であれば、C++テンプレートでC++コンパイラが勝手に最適化してくれますが、RUNTIME時定数では、テンプレートは何の役にも立ちません。RUNTIME時定数というメリットを最大限使って高速化を図ります。Xbyakの使用は、初めてで、SSE2も初めてなので、初めてのXbyakによるSSE2ということで、実装中のコードを使用して、この先書きたいと思います。
今の時代、LLVMがあるので、C++コードのJITコンパイルも可能になっており、その必要性は狭まってはいますが、Xbyakで記述した方が手軽な場合もあります。
例えば、IntelのMKL-DLLという深層学習用の高速化ライブラリがありますが、そのエンジンには、Xbyakが使われているそうです。
https://blog.cybozu.io/entry/2019/04/15/170000
またスパコンCPU aarch64(ARMの64ビットアークテクチャ)にも移植されているようです。
Xbyakの概要はこちら。
今回の使用目的は、機械・深層学習用ではなくて、AL4の高速化です。AL4は、数理的ソルバーですが、部分問題を解く必要があり、そのための新しいアイデアに対する実装に使用します。
コンパイル時定数であれば、C++テンプレートでC++コンパイラが勝手に最適化してくれますが、RUNTIME時定数では、テンプレートは何の役にも立ちません。RUNTIME時定数というメリットを最大限使って高速化を図ります。Xbyakの使用は、初めてで、SSE2も初めてなので、初めてのXbyakによるSSE2ということで、実装中のコードを使用して、この先書きたいと思います。
2020年2月9日日曜日
リーダ1日以上4日以下
下記は、スニペットです。GUIだけで記述できました。
平準化のため、各スタッフ6日以下としていますが、Pythonを使えば、この部分もダイナミック化
が可能です。ダイナミック化とは、動的に例えば6という数字を決定することです。元々、6というのは、
リーダ回数=月の日数/リーダ可能者人数+1
で割り出したはずです。ところが、月の日数は変わるし、リーダ可能者も、スタッフプロパティに現れなくて出来ない人(実習等で予定書き込み)もいるかもしれません。その場合でも、予定を集約すれば、より精度の高い平準化が可能になります。同時に、将来のリーダ可能者の増減にも自動で対応可能となります。ロバストな勤務表づくりの要点は、そういった将来の人数の増減まで考えることです。
平準化のため、各スタッフ6日以下としていますが、Pythonを使えば、この部分もダイナミック化
が可能です。ダイナミック化とは、動的に例えば6という数字を決定することです。元々、6というのは、
リーダ回数=月の日数/リーダ可能者人数+1
で割り出したはずです。ところが、月の日数は変わるし、リーダ可能者も、スタッフプロパティに現れなくて出来ない人(実習等で予定書き込み)もいるかもしれません。その場合でも、予定を集約すれば、より精度の高い平準化が可能になります。同時に、将来のリーダ可能者の増減にも自動で対応可能となります。ロバストな勤務表づくりの要点は、そういった将来の人数の増減まで考えることです。
2020年2月7日金曜日
予定の入っていないところだけ制約する
前回から続きプロジェクト実装です。
確かに、公休数11.5を実現するのに、全休10回、半休3回(長坂さん)でよい雰囲気です。
しかし、例えば横山さんの公休数11を実現するために、全休8日、半日が6日もアサインがされてしまっていて問題です。半日には、何ら制約が入っていないために、こういう解が出てしまいます。
そこで、土曜日以外は、なるべく半日をアサインしないように制約したくなるのですが、元々予定が入っているところは、意味がないので外すことにします。(ソフト制約は、ソルバーにとって重いのでなるべく少なくしたいという意図もあります。)
土曜日だけ半日→土曜以外は半日禁止→今月土曜以外は、半日禁止 というロジックにより
空白のときだけ、半休がアサインされ、レベル1のペナルティを与えるコードになっています。
このコードをEnableすると、土曜日だけ半休がアサインされて下の結果となります。
GUIでは、静的制約しかできませんが、Pythonを使えば、上のようにダイナミックに制約することが出来ます。
確かに、公休数11.5を実現するのに、全休10回、半休3回(長坂さん)でよい雰囲気です。
しかし、例えば横山さんの公休数11を実現するために、全休8日、半日が6日もアサインがされてしまっていて問題です。半日には、何ら制約が入っていないために、こういう解が出てしまいます。
そこで、土曜日以外は、なるべく半日をアサインしないように制約したくなるのですが、元々予定が入っているところは、意味がないので外すことにします。(ソフト制約は、ソルバーにとって重いのでなるべく少なくしたいという意図もあります。)
土曜日だけ半日→土曜以外は半日禁止→今月土曜以外は、半日禁止 というロジックにより
def 土曜以外の半休抑制():
for person in 全スタッフ:
for day in 土曜でない今月:
ts=shift_schedules[person][day][0]
if ts =='':
v=sc3.GetShiftVar(person,day,'半休')
st=staffdef[person]+'土曜以外の半休抑制'
sc3.AddSoft(~v,st,1)
shift_schedules[person[day][0] に予定が入っていればシフトが入ってきます。空白のときだけ、半休がアサインされ、レベル1のペナルティを与えるコードになっています。
このコードをEnableすると、土曜日だけ半休がアサインされて下の結果となります。
2020年2月3日月曜日
スタッフプロパティ事例集更新
https://www.nurse-scheduling-software.com/publications.html
のスタッフプロパティ事例集を更新しました。
病棟のほかに、放射線、介護、TV局、工場 等々あります。
のスタッフプロパティ事例集を更新しました。
病棟のほかに、放射線、介護、TV局、工場 等々あります。
2020年2月2日日曜日
ORのレクチャー
目的関数値とか、スケジュールナースのマニュアルには、時々OR用語が出てきますが、
良い、解説がありました。
http://www.robot.t.u-tokyo.ac.jp/dcm/lec_opt/lec01.pdf
http://www.robot.t.u-tokyo.ac.jp/dcm/lec_opt/lec02.pdf
http://www.dais.is.tohoku.ac.jp/~shioura/teaching/mp11/mp11-06.pdf
見て分かるように、ナップザック問題や最短経路問題は、ナーススケジューリングにおいても重要な部分問題であり、この性能の良し悪しが全体のボトルネックになります。数理最適化において最も重要な解法は、分岐限定法です。分岐限定法は、ポイントが二つあり、ノードの選択とと切除平面です。前者については、Reserchgateの回答がエッセンスです。
https://www.researchgate.net/post/Branch_and_Bound_Algorithm_How_to_choose_variables_in_case_of_more_than_one_fractional_values
切除平面については、色々な方法がありますが、最も基本的なものは、小数カットと呼ばれる方法です。
http://www.orsj.or.jp/~archive/pdf/bul/Vol.48_12_936.pdf
http://infoshako.sk.tsukuba.ac.jp/~maiko/mathpro/n_note2-2.pdf
http://dopal.cs.uec.ac.jp/okamotoy/lect/2013/opt/handout06.pdf
http://www.msi.co.jp/nuopt/glossary/term_167e2968d79e57b147ffb376f70159d277feacb7.html
良い、解説がありました。
http://www.robot.t.u-tokyo.ac.jp/dcm/lec_opt/lec01.pdf
http://www.robot.t.u-tokyo.ac.jp/dcm/lec_opt/lec02.pdf
http://www.dais.is.tohoku.ac.jp/~shioura/teaching/mp11/mp11-06.pdf
見て分かるように、ナップザック問題や最短経路問題は、ナーススケジューリングにおいても重要な部分問題であり、この性能の良し悪しが全体のボトルネックになります。数理最適化において最も重要な解法は、分岐限定法です。分岐限定法は、ポイントが二つあり、ノードの選択とと切除平面です。前者については、Reserchgateの回答がエッセンスです。
https://www.researchgate.net/post/Branch_and_Bound_Algorithm_How_to_choose_variables_in_case_of_more_than_one_fractional_values
切除平面については、色々な方法がありますが、最も基本的なものは、小数カットと呼ばれる方法です。
http://www.orsj.or.jp/~archive/pdf/bul/Vol.48_12_936.pdf
http://infoshako.sk.tsukuba.ac.jp/~maiko/mathpro/n_note2-2.pdf
http://dopal.cs.uec.ac.jp/okamotoy/lect/2013/opt/handout06.pdf
http://www.msi.co.jp/nuopt/glossary/term_167e2968d79e57b147ffb376f70159d277feacb7.html
登録:
投稿 (Atom)



