2020年2月7日金曜日

予定の入っていないところだけ制約する

前回から続きプロジェクト実装です。
確かに、公休数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すると、土曜日だけ半休がアサインされて下の結果となります。

 
GUIでは、静的制約しかできませんが、Pythonを使えば、上のようにダイナミックに制約することが出来ます。

0 件のコメント:

コメントを投稿