0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GLPKによる勤務シフト表の作成1(2)

Last updated at Posted at 2017-03-25

###目次
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") "朝" "夕" "夜"
;

GLPKによる勤務シフト表の作成1(3)->

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?