2019年12月14日土曜日

日曜出勤したらその週のどこかで休む

というご要求を受けたのですが、以下のように実装し、ご要求そのままではありません。
理由は、
1)端数処理が面倒
2)解空間をなるべく狭めたくはない

その週となると、月はじめ、月終わりの処理が面倒になります。休みというシフトも区別する必要があり、例えば代休というシフトを新設する必要があります。そして、今月以外に見る必要も生じます。

第2の問題は、その週に限定すると、解空間が狭まります。

そこで、要求のエッセンスを満たす方式として、日曜出勤した数だけ代休するという処理にしました。以下がコードです。こうすれば、その週に限定することはないので、解空間の減少を極小にすることができ、なおかつ月内処理に限定できるので、実装が簡単になります。



def 日曜日出勤なら代休():
    for person in 全スタッフ:
        if person not in 正社員:
            for day in 全日:
                if day in 今月:
                    s='正社員でなければ全日代休禁止'+daydef[day]
                    v=sc3.GetShiftVar(person,day,'代休')
                    sc3.AddHard(~v,s)
        else:#正社員
            sc3.print('正社員'+staffdef[person]+'の代休処理を行います\n')
            日_list=[]
            代_list=[]
            s='日曜働いた数に代休カウントは等しい '+staffdef[person]#DEC132019
            for day in 全日:
                if day in 今月:
                    if day in 日:
                        s='日は代休禁止'
                        v=sc3.GetShiftVar(person,day,'代休')#日は代休禁止
                        sc3.AddHard(~v,s)
                        v=sc3.GetShiftVar(person,day,'休日')
                        日_list.append(~v)#日曜働いたなら日_listに追加
                    if day in 今月休診日:
                        v=sc3.GetShiftVar(person,day,'代休')#休診日は代休禁止
                        sc3.AddHard(~v,s)
                    else:
                        v=sc3.GetShiftVar(person,day,'代休')
                        代_list.append(v)#稼働日の代休をカウント
            #s='日曜働いた数に代休カウントは等しい '+staffdef[person]
            sc3.AddHard(sc3.SeqComp(日_list,代_list),s)

日曜出勤した分だけ、代休(青色)しているのが分かると思います。

ところで、SeqCompが意外に使い勝手があり、あることを思いつきました。次回これを拡張することを考えます。

0 件のコメント:

コメントを投稿