##勤務スケジューリング問題
スタッフの人数、スケジュール日数、シフトの種類数、避けるべきシフトのパターン、日ごとのシフトごとの必要数が与えられたときに、これらを満たすスケジュールを求めよ。
目的関数や制約には、様々なバリエーションがある。
##実行方法
usage
Signature: shift_scheduling(ndy, nst, shift, proh, need)
Docstring:
勤務スケジューリング問題
入力
ndy: 日数
nst: スタッフ数
shift: シフト(1文字)のリスト
proh: 禁止パターン(シフトの文字列)のリスト
need: シフトごとの必要人数リスト(日ごと)
出力
日ごとスタッフごとのシフトの番号のテーブル
python
from ortoolpy import shift_scheduling
ndy, nst = 8, 4
shift = '休日夜'
proh = ['夜夜', '夜日', '日日日']
need = {'日':[2] * 8, '夜':[1] * 8}
r = shift_scheduling(ndy, nst, shift, proh, need)
print(r)
import numpy as np, pandas as pd
a = pd.DataFrame(np.vectorize(lambda i: shift[i])(r),
columns=[chr(65+i) for i in range(nst)],
index=['%d日目'%i for i in range(1,ndy+1)])
for sft,lst in need.items():
a['%s必要'%sft] = lst
a['%s計画'%sft] = (a.iloc[:,:4]==sft).sum(1)
print(a)
結果
[[0, 1, 2, 1],
[1, 2, 0, 1],
[1, 0, 1, 2],
[2, 1, 1, 0],
[0, 1, 2, 1],
[1, 2, 0, 1],
[1, 0, 1, 2],
[2, 1, 1, 0]]
A B C D 日必要 日計画 夜必要 夜計画
1日目 休 日 夜 日 2 2 1 1
2日目 日 夜 休 日 2 2 1 1
3日目 日 休 日 夜 2 2 1 1
4日目 夜 日 日 休 2 2 1 1
5日目 休 日 夜 日 2 2 1 1
6日目 日 夜 休 日 2 2 1 1
7日目 日 休 日 夜 2 2 1 1
8日目 夜 日 日 休 2 2 1 1
python
# pandas.DataFrame
from ortoolpy.optimization import ShiftScheduling
ShiftScheduling(8, 4, '休日夜', ['夜夜','夜日','日日日'], {'日':[2]*8, '夜':[1]*8})
A | B | C | D | 日必要 | 日計画 | 夜必要 | 夜計画 | |
---|---|---|---|---|---|---|---|---|
1日目 | 休 | 日 | 夜 | 日 | 2 | 2 | 1 | 1 |
2日目 | 日 | 夜 | 休 | 日 | 2 | 2 | 1 | 1 |
3日目 | 日 | 休 | 日 | 夜 | 2 | 2 | 1 | 1 |
4日目 | 夜 | 日 | 日 | 休 | 2 | 2 | 1 | 1 |
5日目 | 休 | 日 | 夜 | 日 | 2 | 2 | 1 | 1 |
6日目 | 日 | 夜 | 休 | 日 | 2 | 2 | 1 | 1 |
7日目 | 日 | 休 | 日 | 夜 | 2 | 2 | 1 | 1 |
8日目 | 夜 | 日 | 日 | 休 | 2 | 2 | 1 | 1 |