2019年11月29日金曜日

年末年始対応その2

年末年始だけの記述は、下Fig.です。
Day集合年末年始は、Excel稼働日から得ていますが、年末年始でないとき、つまり空集合のときは、ソフトエラーがカウントされてしまいます。 ソフトエラーならまだしも、これがハード制約だったとすると解なしになってしまうので、年末年始外はオフにする必要があります。つまりこの制約はメンテナンスフリーではありません。そこで、同じことをPythonで記述します。
空集合でないときだけ制約をEnableするので、年末年始でないときは、制約されません。
Pythonを用いると、このようにダイナミックに判断することができるので、メンテナンス上好ましい形にすることが出来ます。

別な応用としては、稼働日Day集合名及び、集合要素は、仮想的なものでも構わない筈です。
つまり、Day集合中DayIndexに対応する●の有無をその月のPythonに対するコマンドとしても使えます。
 

2019年11月28日木曜日

導入手順書プロジェクトファイル編

書きました。実は、このマニュアルは、ある特養向けのマニュアルです。予定入力についても相談があったので、自分の考えも書き添えました。

2019年11月27日水曜日

組み合わせ最適化の最前線

梅谷先生の論文は、貴重な示唆に富んでいてとても参考になります。

キーワードは、「最適化のための機械学習」です。恐らく、商用ソルバは、既にその仕組みを組み込んでいるのではないかと思います。(NEOS等で自然にインスタンスデータは集まってきます。数年前解けなかった問題が解けるようになっていたりします。)
SATでもそうですが、特徴のない世界、つまりランダム化したインスタンスは無力で僅か数百変数でも難儀することがあります。しかし、人間界のインダストリアルインスタンスは、人間である以上、なにがしかの偏り、特徴があることは必然であり、 そこに解く鍵がある、ということだと思います。BIGデータが勝者と敗者を分ける、そんな波が組み合わせ最適化の世界に来ているということではないでしょうか?

https://speakerdeck.com/umepon/a-practical-approach-for-hard-combinatorial-optimization-problems-in-real-applications

http://www.orsj.or.jp/archive2/or59-01/or59_1_20.pdf

2019年11月26日火曜日

ShiftとTask

Taskは、未だTutorialに書いていません。
ナーススケジューリングの場合、Taskが必要になることはあまりないのですが、確かに必要となる場合があります。例えば、
NRC2(Nurse Scheduling CompetitionⅡ)では、次のような解になります。

いつものSC3と様子が違うのは、1日が4つに分割されていることです。この場合、4Shift1Phase の例になります。一つのシフトに複数の業務の一つを割り振る場合に必要となるのがTaskです。上の例の場合でも、一つのシフトに複数のTaskが割り振られているのが分かります。

あるいは、シフトをさらに2つに分割して、
3Shift2Phaseの例(1日に6個の独立したTaskが記述)も可能です。やはり、午前と午後で別なTaskを割り振るのに加え、早番遅残業があるという工場でのシフト問題で、超難問です。
 
簡単な例では、1Shift2Phaseというのもあります。日勤外来専用のナース配置問題で、
午前と午後で行き先が違う(Taskが異なる)問題です。
 
Shiftは、1日に一つです。Shiftは、時間帯概念です。基本的に、1Shift内では、一つの仕事となります。
その概念を拡張するのがTaskになります。Taskを用いると複数の仕事の中から一つの仕事を割り振ることが出来ます。さらに、シフトを分割するのがPhaseという概念になります。1シフト内に複数のシーケンス(Phase)を持ち、Phase毎に複数の仕事の中から一つの仕事を割り振りたい場合に使います。
 
 
ポイントは、複数の仕事の中から一つの仕事を割り振る必要があるかということです。Taskを用いると次元が増えるためにGUIでは書けなくなる傾向にあります。(従いPythonで書く必要が出てきます。) ですから、なるべくTaskは、使わなくて済むならば使いたくはないです。
一見Taskが必要に見えても、実はShiftだけで非常に細かく書ける例も存在します。そのような例を次回紹介します。
 
 
 
 
 

2019年11月14日木曜日

Incident Report Continued...

Hi Takayuki,
ライブラリバグではなくて、私のライブラリ使用の仕方に問題があったようです。
Syncfusion社さま、ごめんなさい。

123Aで修正しました。

Thanks for your patience.
We maintain the maximum limit of interior functions as 100 by default. The reported issue occurs when the limit exceeds the default value. This can be avoided by assigning some high value for [a:https://help.syncfusion.com/cr/cref_files/windowsforms/Syncfusion.Calculate.Base~Syncfusion.Calculate.CalcEngine~MaximumRecursiveCalls.html]MaximumRecursiveCalls property of CalcEngine. Please find the code snippet below.
Code snippet:

//To increase the maximum limit for interior functions
worksheet.CalcEngine.MaximumRecursiveCalls = 1000;
Please look into the following link to know more about limitations in CalcEngine.
Help Link: https://help.syncfusion.com/windowsforms/calculate/performance

P.S.
私事ですが、身内に不幸がありしばらくお休みします。

2019年11月13日水曜日

年末年始対応

盆と正月は、大抵のプロジェクトで特別な対応が必要になります。

下は、クライアントプロジェクトの「今月」になります。通常月の今月は、(1日から月末まで)になりますが、「今月」は、(12月1日から1月4日まで)になります。

クライアントの祝定義は、下の通りです。(病院で異なります。妻のところは、9連休らしいです。)
来月の定義も必要になります。
そうすると、公休数や、夜勤数は、「今月」ではなく12月に限定する必要があります。
それが「来月ではない今月」になります。
あとは、計数部分に対してこの定義を適用すればよいです。
この職場の場合、(前月19日から今月18日まで)期間も同じようような制約がかかっています。
年末年始は、
・年末勤務した場合 年始優先
・年始勤務した場合 年末を優先
というご要望を頂いていたのですが、解を出してみると出勤回数は、2回程度でしたので、単純に年末年始内の勤務数を制約することにしました。(意図は、平準化であると考えました。)
このプロジェクトは、メンテナンスフリーではありません。
「来月でない今月」は、年末年始が定義されていない(空集合)状態でも問題にはなりません。
しかし、年末年始内制約は、定義されていない場合エラーとなる可能性があります。
つまり、年末年始でないときは、制約を適用しない操作(適用を外す)が必要となります。

GUIでは、この辺が限界です。次回、同じ処理をPythonで書いてメンテナンスフリー化を試みることにします。

2019年11月12日火曜日

Incident Report Continued..

数ヶ月は、覚悟していたのですが、意外に早いかもしれません。

Hi Takayuki,
Greeting from Syncfusion.
The Excel documents you have shared us (correct.xlsx and wrong.xlsx) have same formula =IF(D5<>"",IF($D$5+COLUMN()-COLUMN($D$5)<=$C$2,$D$5+COLUMN()-COLUMN($D$5),""),"") . However we have modified the formula in wrong.xlsx document as =IF(D5<>"",IF(D5+1<=$C$2,D5+1,""),"") and tried to reproduce the issue.
The CalculatedValue is returned improperly from AK5 cell instead of AM5 cell up to BP5 cell. We have forwarded this issue to our development for further validation. We will update further details on 13th November 2019.

2019年11月11日月曜日

チュートリアル動画作成構想

ナレーションの問題は、AIトークが素晴らしいのですが、いかんせん価格で手がでません。
しかし、最近合成技術が進歩しており、Google、Amazon,MicrosoftでText To Speechを従量課金で、手に入れることができます。WEBのデモが殆どないので、全部を試せてないのですが、そこそこといったレベルでしょうか。未だ違和感があります。
参考にしたのは、

https://blog.systemjp.net/entry/2019/03/26/125644
https://azure.microsoft.com/ja-jp/services/cognitive-services/text-to-speech/
https://qiita.com/yukari120/items/70cdea43743f4a35d85c

https://ttsmp3.com/
最後は、探していたWEBサービスですが、これを使って操作動画を作ってみようかな、と思います。

2019年11月10日日曜日

スケジュール(予定入力)のExcelエクスポート

121Aから実装しています。

Excelから予定入力をImportするのと反対です。この意味は、二つあって、予定入力の段階で、Excelに落としたい場合と、解出力→予定入力へ送る でExcel入力フォームに解を送る
という意味があります。

方法は、Import設定をするのと同じです。(Import設定済みならOKです。)
後は、予定入力から右クリックでExcel出力をクリックしてください。

Excelの予定入力シートをコピーしておきます。(勤務表SC3シート)
書き込むシートにチェックします。

解を求めるときの予定入力状態です。

解を求め予定入力に送ります。

Excelへ送ります。
Excelを開いていると次のようなエラーが出るので、閉じてください。

しっかり解が書き込めました。

私的には、勤務表の設定開発時に、人力解とソフト解の比較に使っています。Excelでスタッフ属性を読むシートは、共通で、全入力(人力解)シート とソフト解(予定だけを入れた)シートだけを分けて、読み込むと他のパラメータを共通にして、解の品質評価が出来ます。つまり一つのプロジェクト
で、人力解とソフト解の品質比較が出来るようになります。プロジェクトが分かれているとあれやこれで、どうしてもパラメータが異なってしまいがちですが、これだと、きっちり入力だけを交換して解の比較ができます。入力を全て埋めた人力解にすれば、人力解とソフト解の比較が出来ます。

ユーザさんのプロジェクトは、仕様というより願望を書いてこられる方が多いです。
そのままSC3解を出しても、満足していない状況には変わりないので、あまり説得力がありません。ところが人力解と比較すると、圧倒的に高品質なので、ぐっと印象が良くなるという仕掛けです。
(目的関数値が実力テストの比較に使えます。0点が一番良いのですが。)

現状認識をまずきちっとやってもらって、「そこからこれだけ良くなる」 というアプローチが重要です。 

2019年11月9日土曜日

Incident Report

使用している商用Excelライブラリでバグがあり、ベンダに対して改善を要求しました。


An  attached excel behavior shows expected behavior. 
Wrong formula calculation occurs in wrong.xlsx
No wrong formula calculations have been seen in correct.xlsx.

The difference between two excel files are as follows
wrong  E5 cell:=IF(D5<>"",IF(D5+1<=$C$2,D5+1,""),"") 
correct E5 cell:=IF(D5<>"",IF($D$5+COLUMN()-COLUMN($D$5)<=$C$2,$D$5+COLUMN()-COLUMN($D$5),""),"")


Apparent wrong calculation starts from AM5 cell in wrong.xlsx
Please note it should result identical results between two excels though they have different formula.
It seems incremental rather deep formula reference causes the wrong calculation.