###目次
GLPKによる勤務シフト表の作成1(1) (基礎編) (2)←ここ (3) (4)
GLPKによる勤務シフト表の作成2 (2日連続して勤務する場合の勤務シフト)
データセクションでの指定
モデルとデータを別のファイルにすることができますが、data;行で分けることで1つのファイルに記入できます。
モデル部分とデータセクションによってデータの書き方が全く違いますので気をつけてください。
前回から
営業時間帯の指定
スタッフの従事時間帯、休みの指定
ができるようになっています。
データの後に;が付いていますので忘れないように。
データセクションの書き方はGLPKに同梱されているgmpl.pdfの「5 Model data」に詳しく書かれていますので参考に。
営業時間帯を指定できるようになりましたので、エラーを回避するために
: (d,t) in BusinessHour
が追加されている部分があります。
改良版
shift2.model
# version 0.11
# シフト表作成
param firstDate; # 期間の最初の日付
param endDate; # 最後の日付
set Date := firstDate..endDate; # 期間内の日付
set TimeSlot := {"朝", "夕", "夜"}; # シフト時間枠
set Staff; # スタッフ名
param maxWorkingDays{Staff}; # 各スタッフの最大勤務日数
set BusinessHour dimen 2; # 営業時間帯
set FixOnDuty dimen 3; # 勤務時間帯
set FixOffDuty dimen 3; # 非番時間帯
# 日付,シフト時間枠,スタッフの配列を確保、出勤の割り当ては1が入る
var assignShiftSchedule{BusinessHour, Staff} binary;
# シフト時間枠に必ず1人従事
s.t. keepStaffInTimeSlot{(d,t) in BusinessHour}: sum{s in Staff}assignShiftSchedule[d,t,s]==1;
# 出勤は1日1回以下
s.t. avoidShiftPatten1{s in Staff, d in Date}: sum{(d,t) in BusinessHour}
assignShiftSchedule[d,t,s]<=1;
# 各スタッフの最大勤務日数で制限
s.t. restrictMaxWorkDays{s in Staff}: sum{(d,t) in BusinessHour}
assignShiftSchedule[d,t,s]<=maxWorkingDays[s];
# 連続勤務は3日以下
s.t. keepOffDay{s in Staff, d in firstDate..endDate-3}: sum{t in TimeSlot, d4 in d..d+3 : (d4,t) in BusinessHour}
assignShiftSchedule[d4,t,s]<=3;
# 翌日の勤務時間帯を制限
s.t. avoidShiftPatten2{s in Staff, d in firstDate..endDate-1}: sum{(d1, t) in {(d, "夕"), (d, "夜"), (d+1, "朝")} :(d1,t) in BusinessHour}
assignShiftSchedule[d1,t,s]<=1;
s.t. avoidShiftPatten3{s in Staff, d in firstDate..endDate-1}: sum{(d1, t) in {(d, "夜"), (d+1, "朝"), (d+1, "夕")} :(d1,t) in BusinessHour}assignShiftSchedule[d1,t,s]<=1;
# スタッフが従事する時間帯を指定
s.t. fix1{(d,t,s) in FixOnDuty}: assignShiftSchedule[d,t,s]=1;
# スタッフが出勤できない時間帯を指定
s.t. fix2{(d,t,s) in FixOffDuty}: assignShiftSchedule[d,t,s]=0;
solve;
# 出力
for{d in Date}{
printf "%2d ", d;
for{t in TimeSlot : (d,t) in BusinessHour}{
printf{s in Staff : assignShiftSchedule[d,t,s]==1}" %s", s;
}
printf "\n";
}
data;
# 期間の最初の日付と最後の日付
param firstDate:=1;
param endDate :=13;
# スタッフ名と最大勤務日数
param : Staff : maxWorkingDays :=
"A" 9
"B" 9
"C" 9
"D" 9
;
# 営業時間帯
set BusinessHour :=
(1, *) "朝" "夕" "夜"
(2, *) "朝" "夕" "夜"
(3, *) "朝" "夕" "夜"
(4, *) "朝" "夕" "夜"
(5, *) "朝" "夕" "夜"
(6, *) "朝" "夕"
# 7日は休業
(8, *) "朝" "夕" "夜"
(9, *) "朝" "夕" "夜"
(10, *) "朝" "夕" "夜"
(11, *) "朝" "夕" "夜"
(12, *) "朝" "夕" "夜"
(13, *) "朝" "夕"
;
# スタッフが従事する時間帯を指定
set FixOnDuty :=
(1, "朝", "A")
(1, "夕", "B")
(1, "夜", "C")
;
# スタッフが出勤できない時間帯を指定
set FixOffDuty :=
(2, *, "A") "朝" "夕" "夜"
(3, *, "B") "朝" "夕" "夜"
;