Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

人と人の相性を考慮したシフトスケジューラ

4,269 views

Published on

PyConJP 2019 Talk Session
PythonとGoogle Optimization Toolsの最適化ライブラリで、「人と人の相性を考慮したシフトスケジューラ」を作ってみた。

Published in: Data & Analytics
  • Be the first to comment

人と人の相性を考慮したシフトスケジューラ

  1. 1. ㈱リーディングエッジ社 鈴木 庸氏 (Youji Suzuki) PyConJP2019 Talk Session 1
  2. 2. 1. Introduction 2. Self-Introduction 3. Demonstration 4. Google Optimization Tools 5. シフトスケジューラ概要 6. シフトスケジューラ実装 7. まとめ 8. 今後は・・・ 2
  3. 3. 今日のトークセッションで伝えたいこと ① PythonとOSS数理最適化ソルバーを ビジネスに役立てよう ② Google Optimization Toolsを使ってみよう ③ シフト・スケジューリングについて知ろう 3
  4. 4. 鈴木 庸氏(すずき ようじ) } Python歴 5年 } 所属 リーディングエッジ社 } 年齢 47歳 } 出身 千葉県君津市 } 業務 Python 物流の組合せ最適化、シミュレーション } 好きなこと 釣り、ドライブ 4
  5. 5. Development Supporter 田端 哲朗(たばた てつろう) } Python歴 2年 } 所属 リーディングエッジ社 } 年齢 41歳 } 出身 石川県 } 業務 Java開発(業務システム開発等) } 好きなこと キャンプ 5
  6. 6. Let’s make a shift schedule! 6
  7. 7. シフトスケジューラとは? ・ 商業店舗や病院の ・ 与えられた条件に沿ったシフト勤務表を ・ 自動作成してくれるアプリケーションです 7
  8. 8. Here We Go! デモを見てみましょう 8
  9. 9. 3.1 シフトスケジューラ起動 勤務表作成ボタン 9
  10. 10. 3.2 立案開始日、立案期間、人数を入力 立案開始日 立案期間 人数 10
  11. 11. 3.3 従業員名、勤務可能なシフトを入力 勤務可能シフト 従業員名 11
  12. 12. 3.4 シフト必要人数の入力 各シフトの必要人数 12
  13. 13. 3.5 従業員どうしの相性の入力 相性得点 マトリクス 13
  14. 14. 3.6 同一シフト連続条件の入力 同一シフト連続条件 14
  15. 15. 3.7 シフト勤務表作成結果 従業員の 勤務シフト表 15
  16. 16. OR-Tools is fast and portable software for combinatorial optimization https://developers.google.com/optimization 16
  17. 17. 4.1 数理最適化ソルバーとは? ・ 与えられたルール(制約)の中で ・ もっとも良い答えを見つけてくれるソフトウェア ・ 例えば、 主人 宝物はこの畑のどこにある? イヌ ここ掘れワンワン! → 最適解:座標(x、y) (目的関数:宝物の価値 説明変数 x、y座標) 17
  18. 18. } Pythonから利用できる数理最適化のためのオープンソフトウェ アスィート } 整数計画、線形計画、制約プログラミングにおける問題を解くこ とができる } CBC、GLOP、CP、CP-SATなどの数理最適化ソルバーを利用 できる https://developers.google.com/optimization より 4.2 Google Optimization Toolsとは? 18
  19. 19. } CBC coin-or.orgが開発している混合整数計画ソルバー } GLOP Googleが開発している線形計画ソルバー } CP Googleが開発している制約計画ソルバー、2次式が使えて便利 } CP-SAT Googleが開発している制約計画ソルバー、CPの後継 4.2 利用できるソルバー(抜粋) 19
  20. 20. シフト勤務のお仕事 看護師の勤務シフト 店舗の勤務シフト 工場の勤務シフト コールセンターの勤務シフト 20
  21. 21. ① シフトスケジュール作成には熟練者が必要 熟練者は減少傾向にあり、技能伝承および担保が求められている ② 人によるシフトスケジュール作成には多大な時間がかかる 休暇日などの勤務時間外にシフトを作るケースが多い (シフトスケジュール作成者の悩みの種) ③ 市販の汎用スケジューラでは、暗黙知的ルールを考慮できない 数理最適化を使った専用シフトスケジューラでは、暗黙知的ルール を制約条件、評価条件として組み込むことが可能 5.1 シフト作成における課題 21
  22. 22. ・シフト開始日 ・シフト立案期間 ・従業員の人数 ・従業員の勤務可能条件 ・各シフトの必要人数 ・従業員どうしの相性 (暗黙知的ルール) ・連続勤務可能条件 ・夜勤明けの勤務可能条件 5.1 シフト作成での考慮すべき条件 22
  23. 23. ① 導入コストにおけるメリット ・ PythonとGoogleのソルバーでコストを抑え、 商用ソルバーよりもはるかに導入しやすい (商用ソルバー価格は500万円以上) ② 従業員にもたらすメリット ・ スケジュール作成負荷の低減 施設全体での生産効率向上 従業員の働きやすさ改善 5.2 シフトスケジューラ導入によるメリット 23
  24. 24. ・ シフトスケジューリングは割り当て問題であるので、 次のような決定変数を考える 従業員nを、日dの、シフトsに割り当てるか否か? 決定変数 x[n, d, s] (割り当てないとき:0、割り当てるとき:1) 6.1 モデリング-決定変数 24
  25. 25. 従業員nを、日dの、シフトsに、割り当てるか否か? 6.1 モデリング-決定変数 日 \シフト 日勤 準夜勤 夜勤 1日目 1 0 0 2日目 1 0 0 3日目 0 0 0 決定変数x[n, d, s] 従業員n シフトs 日d 割り当てる:1 割り当てない:0 25
  26. 26. ・ 制約条件は決定変数を使った不等式で表現できる 次のように、シフト人数制約を定義する シフト人数制約式 ① 「日d、シフトs」に割り当てる人数合計 ≦ シフト人数Max ② 「日d、シフトs」に割り当てる人数合計 ≧ シフト人数Min 6.2 モデリング-シフト人数制約 26
  27. 27. ・ 制約式① 「日d、シフトs」に割り当てる人数合計 ≦ シフト人数Max solver.Sum( [x[n, d, s] for n in 全従業員]) <= シフト人数Max 6.2 モデリング-シフト人数制約 従業員 日勤 準夜勤 夜勤 従業員1 1 0 0 従業員2 1 0 0 従業員3 0 1 0 従業員4 0 1 0 従業員5 0 0 1 従業員6 0 0 1 ある日d、あるシフトsの決定変数x[n, d, s] シフトs 従 業 員 n シフトに組まれた 人数を数える 27
  28. 28. ・ 目的関数は決定変数を使った数式で表現できる 次のように、目的関数を定義する 目的関数 目的関数式① 各従業員の勤務回数を平準化する 目的関数式② 従業員どうしの相性の合計を最大化する 6.3 モデリング-目的関数 28
  29. 29. ・目的関数① 従業員の勤務回数を平準化する 6.3.1 モデリング-目的関数① 出勤回数Maxと 出勤回数Minを取得 して、差を最小化 出勤回数Maxと、出勤回数Minの差を、最小化する 29
  30. 30. ・出勤回数Max、出勤回数Minは不等式で表現できる ・出勤回数Max、出勤回数Minの差を最小化する for n in N: 勤務回数Max ≧ solver.Sum( [x[n, d, s] for d in D for s in S]) 勤務回数Min ≦ solver.Sum( [x[n, d, s] for d in D for s in S]) solver.Minmize(勤務回数Max -勤務回数Min) N:全従業員の集合 D:全日の集合 S:全シフトの集合 6.3.1 モデリング-目的関数① 30
  31. 31. ・目的関数② 従業員どうしの相性の合計を最大化する 従業員n1と従業員n2の相性を合計することで表現できる 6.3.2 モデリング-目的関数② 全てのシフトで、同じシフトに 割り当てられた従業員n1と従 業員n2の相性を合計する 31
  32. 32. ・目的関数② 従業員どうしの相性の合計を最大化する 従業員n1と従業員n2の相性を合計することで表現できる しかし、 x[n1, d1, s1] * x[n2, d2, s2] は2次式なので混合整数計画 ソルバーには、式を入力できない。 solver.Maximize( solver.Sum( [ x[n1, d1, s1] * x[n2, d2, s2] * 相性[n1, n2] for n1 in range(N) for d1 in range(D) for s1 in range(S) for n2 in range(n1,N) for d2 in range(D) for s2 in range(S)] ) ) # N:全従業員数 D:全日数 S:全シフト数 6.3.2 モデリング-目的関数② その1 32
  33. 33. ・ 従業員n1をシフトd1, s1に、従業員n2をシフトd2, s2に割り当てるか否かの 決定変数yを考える y[n1, d1, s1, n2, d2, s2] ・ 決定変数xと決定変数のyの関係を以下の3つの不等式制約によって表現できる y[n1, d1, s1, n2, d2, s2] >= x[n1, d1, s1] + x[n2, d2, s2] – 1 y [n1, d1, s1, n2, d2, s2] <= x [n1, d1, s1] y [n1, d1, s1, n2, d2, s2] <= x [n2, d2, s2] ・従業員どうしの相性の合計を1次式で表現する 6.3.2 モデリング-目的関数② その2 33
  34. 34. 6.3.2 モデリング-目的関数② その2 34 ・ 従業員n1とn2を同じシフトに割り当てたときに1、そうでないときに0となる 行列Aを考える A[n1, d1, s1, n2, d2, s2] ・ 相性の合計を決定変数yと行列Aによって表現できる 一次式になるので、混合整数計画ソルバーに式を入力できる solver.Sum( [y[n1, d1, s1, n2, d2, s2] * A[n1, d1, s1, n2, d2, s2] * 相性[n1][n2] for n1 in range(N) for d1 in range(D) for s1 in range(S) for n2 in range(n1,N) for d2 in range(D) for s2 in range(S)] ) # N:全従業員数 D:全日数 S:全シフト数
  35. 35. CBCの相性合計が一番良いが、計算時間を考えるとCPが良い結果となった。 しかし、制約条件を広げるとCPでは解が出せなかったため、開発にはCBCを採 用した。 *上記は、厳密な比較検証ではなく、あくまで一例です。 6.4 ソルバー比較検証 ・ 下記ソルバーで制約条件を絞った1週間分の立案を実施 35
  36. 36. OS Windows10、Ubuntu 言語 Python 3.7.3 パッケージ or-tools (Google Optimization Tools) Django Pandas ブラウザ Google Crome 6.5 開発環境 36
  37. 37. ・ フリーのソルバーでも高速な立案が可能 8名×1か月のシフト計算時間は 相性考慮無しcase → 30秒 相性考慮有りcase → 30分 ・ 並列処理により、立案対象人数の拡張が可能 6.6 計算速度 37
  38. 38. ・ PythonとGoogle Optimization Toolsでシフト スケジューラを作成できた。ソルバーにはCBCを 使用した。 ・ ソルバーに数式を入力するだけでは、問題規模が 大きくて、実用時間で解くことができなかった。 問題を時間軸に分割し、実用時間で解くことができた。 38
  39. 39. ① ベータ版Webサービスの公開 ② ユーザ・データでの検証 ユーザ様、絶賛募集中! 39
  40. 40. 40
  41. 41. 41

×