2020年6月30日火曜日

有給日数の最小化

有給も含めて勤務計算を行っている職場では、経営上の観点からは、できるだけ少ないほうが望ましい。そのようなスクリプトです。この例の職場では、半日単位で、有給、公休があります。経営的には、最小有給を取得させた上で、公休で済ませることができればその方が望ましいということです。
個人単位では、行制約で、有給0を目指せばよいのですが、目指したいのは、全体の有給を最小することです。そのためには、全員の有給を加算して、 その和が0になるようにする必要があります。これは、GUIでは書けないので、Pythonの出番です。元々有給設定しているスクリプトに僅か2-3行追加で実現可能です。 予め個人単位で、今月は、最小これ以上取得するというmin値が決まっているので、それより小さい数を目指すことは、意味がありません。ですので、各個人の最小値の和が目指すべき最小値となります。後は、ソフトレベル(ここでは5)の重みを変えてやれば、好みの優先度で最小化が実現できます。
#post operation
def 有給日数設定OneShift():
    min_sum=0;
    vlist_sum=[];
    for person in 全スタッフ:
        max=-1
        min=0

        st=staffdef[person]+' 有給日数を制約'
        sc3.print(st+'します。\n')
        if person in 有給日数最大:
                max=有給日数最大[person]#float
        if person in 有給日数最小:
                min=有給日数最小[person]#float
        
                    

        max *=2
        min *=2
        min_sum+=min;
        if isinstance(max, float) and not max.is_integer():
            sc3.print('勤務日数設定でmaxが整数型ではありません。')
            continue
        if isinstance(min, float) and not min.is_integer():
            sc3.print('勤務日数設定でminが整数型ではありません。')
            continue

        max =int(max) #float to int
        min =int(min) #float to int
        sc3.print('最大='+str(max)+' 最小='+str(min)+'\n')
        vlist=[]
        for day in 今月:#午前・午後の日勤と有給taskと有給シフトをカウントする 有給シフトは、2回分
            v=sc3.GetTaskVar(person,day,0,'有給');#AM
            vlist.append(v)
            v=sc3.GetTaskVar(person,day,1,'有給');#PM
            vlist.append(v)

        sc3.AddSoft(sc3.SeqError(min,max,1,vlist),st,7)
        vlist_sum+=vlist;
    sc3.AddSoft(sc3.SeqError(min_sum,min_sum,10,vlist_sum),'Total有給の極小化',5)#重みは調整ください

#Main rountine
有給日数設定OneShift()


0 件のコメント:

コメントを投稿