Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # version 0.2 GLPK
- set Day; # カレンダーの日付
- set Holiday; # 休業日
- set WorkingDay := Day diff Holiday; # 稼働日
- set ProductName; # 製品名
- param lotSize{ProductName} symbolic; # 1ロットの生産数量
- param workerHour{ProductName}; # 1ロットの工数
- param minNLot{ProductName} integer; # 1日の最底ロット数
- param maxNLot{ProductName} integer; # 1日の最大ロット数
- set RestrictPlan dimen 2 within WorkingDay cross ProductName; # 生産日が限定される条件読み込み
- set RestrictProduct := setof{(d,p) in RestrictPlan}(p); # 生産日が限定される製品
- set AvailableDayProduct := {WorkingDay, ProductName diff RestrictProduct} union RestrictPlan; # 製品別の生産可能な日
- param totalProductionLot{ProductName} integer;
- param workerHourRatio{WorkingDay} default 1.0; # 目標工数比率
- param targetWorkerHour{d in WorkingDay} := (sum{p in ProductName}totalProductionLot[p]*workerHour[p]/sum{d1 in WorkingDay}workerHourRatio[d1])*workerHourRatio[d]; # 日別の目標工数
- # 設定値の出力
- printf "期間中のロット総数 総生産数 総工数\n";
- for{p in ProductName}{
- printf "%s %8d %8d %8.2f\n", p, totalProductionLot[p], totalProductionLot[p]*lotSize[p],totalProductionLot[p]*workerHour[p];
- }
- printf "\n";
- printf "日ごとの目標工数\n";
- for{d in Day}{
- printf "%s " & (if d in WorkingDay then "%8.2f" else " -") & "\n", d, targetWorkerHour[d];
- }
- printf "\n";
- printf (if card(RestrictPlan) >0 then "生産可能日が限定される製品\n" else "");
- for{p in RestrictProduct}{
- printf "%s ", p;
- printf{(d,p) in RestrictPlan} " %s", d;
- printf "\n";
- }
- printf (if card(RestrictPlan) >0 then "\n" else "");
- var nLotTable{AvailableDayProduct} integer, >=0; # 日別製品別ロット数
- var totalWorkerTime{WorkingDay}; # 日別総工数
- var binaryForNLot{AvailableDayProduct} binary; # ロット数制限用
- var differenceFromTargetWorkerTime{WorkingDay} >=0; # 目標工数との差
- s.t. sumLot{p in ProductName}: sum{d in WorkingDay: (d,p) in AvailableDayProduct}nLotTable[d,p]==totalProductionLot[p]; # ロット数合計を合わす
- s.t. maxLotNum{(d,p) in AvailableDayProduct}: nLotTable[d,p]<=maxNLot[p]*binaryForNLot[d,p]; # 最大ロット数に制限
- s.t. minLotNum{(d,p) in AvailableDayProduct}: nLotTable[d,p]>=minNLot[p]*binaryForNLot[d,p]; # 最小ロット数に制限
- s.t. sumWorkerTime{d in WorkingDay}: sum{p in ProductName:(d,p) in AvailableDayProduct}nLotTable[d,p]*workerHour[p]==totalWorkerTime[d];
- s.t. diffWorkerTime1{d in WorkingDay}: totalWorkerTime[d]-targetWorkerHour[d]<=differenceFromTargetWorkerTime[d];
- s.t. diffWorkerTime2{d in WorkingDay}: totalWorkerTime[d]-targetWorkerHour[d]>=-differenceFromTargetWorkerTime[d];
- minimize diffminWT: sum{d in WorkingDay}differenceFromTargetWorkerTime[d];
- solve;
- # 結果出力
- printf "日ごとの生産数\n";
- for{d in WorkingDay}{
- printf "%s 総工数 %10.2f\n", d, totalWorkerTime[d];
- printf " 製品名 ロット数 生産数 工数\n";
- printf{p in ProductName: (d,p) in AvailableDayProduct and nLotTable[d,p]>0} " %s %8d %8d %8.2f\n", p, nLotTable[d,p], nLotTable[d,p]*lotSize[p], nLotTable[d,p]*workerHour[p];
- }
- data;
- # 一日の生産ロット数は0または1日の最低ロット数以上1日の最大ロット数以下になる
- # 製品名 1ロットの数量 1ロットの工数 1日の最低ロット数 1日の最大ロット数
- param : ProductName : lotSize workerHour minNLot maxNLot:=
- "製品1" 3000 3000 1 2
- "製品2" 1800 1800 1 3
- "製品3" 1800 1800 1 3
- "製品4" 1900 1900 1 2
- "製品5" 2160 2160 1 2
- "製品6" 1440 1440 1 1
- "製品7" 1900 1900 1 1
- "製品8" 1260 1260 1 2
- "製品9" 2520 2520 1 1
- "製品10" 2080 2080 1 2
- ;
- # カレンダーの日付
- set Day:= 1 2 3 4 5 6 7;
- # 休業日 出力はカレンダーの日付で行うが生産を割り当てない
- set Holiday := 3 4;
- # 製品の総生産ロット数
- param totalProductionLot :=
- "製品1" 1
- "製品2" 5
- "製品3" 3
- "製品4" 2
- "製品5" 3
- "製品6" 2
- "製品7" 2
- "製品8" 2
- "製品9" 1
- "製品10" 3
- ;
- # 生産日が限定される製品名とその日付
- set RestrictPlan :=
- (*, "製品1") 1 2 5 # 製品1を1 2 5 日に限定
- (*, "製品2") 1 2 5
- (*, "製品3") 1 2 5
- (*, "製品4") 2 5 6
- (*, "製品5") 2 5 6
- (*, "製品6") 2 5 6 # 製品6を2 5 6 日に限定
- (*, "製品7") 5 6 7
- (*, "製品8") 5 6 7
- (*, "製品9") 5 6 7
- (*, "製品10") 5 6 7
- ;
- # 行事等で目標工数を変えたい場合 日付と比率
- param workerHourRatio :=
- # 7 0.8 # 先頭の#を外すと稼働日の目標工数が変えられる、12日が8割に減少
- ;
- end;
Advertisement
Add Comment
Please, Sign In to add comment