SlideShare a Scribd company logo
1 of 53
Rubyによる組合せ最適化
Masaki Takeuchi @m4i
2015-11-13 RubyWorld Conference 2015
Masaki Takeuchi
竹内 真樹
@m4i
ウィンワークス株式会社
Chief Scientist
本日の内容
1
• 最適化問題とは何か
2
• 応用分野と勤務スケジューリング問題
3
• なぜRubyを使うのか
本日の内容
1
• 最適化問題とは何か
2
• 応用分野と勤務スケジューリング問題
3
• なぜRubyを使うのか
利益を最大化するには?
製品X
製品Y
原料A
原料B
2kg
1kg
2kg
3kg 12kg
18kg
利益を最大化するには?
製品X 製品Y 利用可能量
利益 2 3
原料A 1 2 12
原料B 3 2 18
利益を最大化するには?
製品X 製品Y 利用可能量
利益 2 3
原料A 1 2 12
原料B 3 2 18
6個
×6 = 12
×6 = 6
×6 = 18
利益を最大化するには?
製品X 製品Y 利用可能量
利益 2 3
原料A 1 2 12
原料B 3 2 18
6個
18 = 6×
12 = 6×
12 = 6×
利益を最大化するには?
製品X 製品Y 利用可能量
利益 2 3
原料A 1 2 12
原料B 3 2 18
利益を最大化するには?
製品X 製品Y 利用可能量
利益 2𝑥 + 3𝑦
原料A 𝑥 + 2𝑦 ≤ 12
原料B 3𝑥 + 2𝑦 ≤ 18
定式化 (formulation)
maximize
subject to
2𝑥 + 3𝑦
𝑥 + 2𝑦 ≤ 12
3𝑥 + 2𝑦 ≤ 18
𝑥, 𝑦 ≥ 0
𝑥, 𝑦 は整数
目的関数
(objective function)
制約条件
(constraint)
最適化問題 (optimization problem) とは
条件を満たす解の中で最適なものを求める問題
数理最適化 (mathematical optimization)
目的関数と制約条件が線形式
線形最適化 (linear optimization)
変数が整数
整数最適化 (integer optimization)
最適化ソルバ
• 定式化した数理モデルを与えると結果を返してくれる
• 無料のものから有料のものまでさまざま
• 本日は Gurobi Optimizer を利用
Rubyによる最適化プログラム
maximize
subject to
2𝑥 + 3𝑦
𝑥 + 2𝑦 ≤ 12
3𝑥 + 2𝑦 ≤ 18
𝑥, 𝑦 ≥ 0
𝑥, 𝑦 は整数
require 'gurobi‘
model = Gurobi::Model.new
x = model.add_var(vtype: :integer)
y = model.add_var(vtype: :integer)
model.maximize x * 2 + y * 3
model.add_constr x + y * 2 <= 12
model.add_constr x * 3 + y * 2 <= 18
model.optimize
https://github.com/m4i/gurobi-jruby を利用
本日の内容
1
• 最適化問題とは何か
2
• 応用分野と勤務スケジューリング問題
3
• なぜRubyを使うのか
最適化の事例
試合スケジュール決定
• NFLの17週間の256試合のスケジュール作成
ガスの生産最適化
• ガス経路計画
• ガスの仕様、未精製ガスの生産バランスに関する将来計画
発電所用ダムへの水の流路、流量の決定
• コロンビア川に直列に並ぶ6つの発電所ダムへの最適配水
• 環境保護、保養、洪水制御などの制約を満たしダムを最適管理
引用元: http://www.octobersky.jp/casestudy/
勤務スケジューリング
勤務スケジューリングは何が大変?
分類 具体例
1 就業規則に基づいた休日割り当て 連続勤務日数、各月の公休日数
2 現場の運用に合った適切なスタッフの配置 開店、閉店時のスタッフ、催事対応
3 繁閑に整合した人数配分 平日、週末の忙しさに応じた人数配分
4 各スタッフの希望
公休の希望、アルバイトスタッフの勤務可能
日
5 公平で、無理のないシフト割り当て
早番/遅番の回数、休日の公休割り当て、遅
番の翌日は早番にしない
6 総就業時間予算以内のシフト割り当て 繁忙月と閑散月の人件費のコントロール
勤務スケジューリングの定式化
変数 𝑤𝑖𝑗𝑘 は
「𝑖 日にスタッフ 𝑗 がシフト 𝑘 に
就くかどうか」
𝑤𝑖𝑗𝑘 ∈ {0,1}
𝑤𝑖𝑗𝑘
スタッフ𝑗
日にち 𝑖
勤務スケジューリングの定式化
1人のスタッフが1日に就くことが
できるシフトは1つだけ
𝑤𝑖𝑗𝑘
スタッフ𝑗
日にち 𝑖
勤務スケジューリングの定式化
1人のスタッフが1日に就くことが
できるシフトは1つだけ
勤務スケジューリングの定式化
1人のスタッフが1日に就くことが
できるシフトは1つだけ
∀𝑖∀𝑗 ෍
𝑘
𝑤𝑖𝑗𝑘 = 1
෍ = 1
勤務条件を表す制約式の例
金曜日の昼はスキルAを持った人が1人以上いなくてはならない
𝑤𝑖𝑗𝑘
スタッフ𝑗
日にち 𝑖
スキルA
勤務条件を表す制約式の例
金曜日の昼はスキルAを持った人が1人以上いなくてはならない
𝑤𝑖𝑗𝑘
スタッフ𝑗
日にち 𝑖
スキルA
勤務条件を表す制約式の例
金曜日の昼はスキルAを持った人が1人以上いなくてはならない
𝑤𝑖𝑗𝑘
スタッフ𝑗
日にち 𝑖
金曜日
勤務条件を表す制約式の例
金曜日の昼はスキルAを持った人が1人以上いなくてはならない
𝑤𝑖𝑗𝑘
スタッフ𝑗
日にち 𝑖
金曜日
勤務条件を表す制約式の例
金曜日の昼はスキルAを持った人が1人以上いなくてはならない
𝑤𝑖𝑗𝑘
スタッフ𝑗
日にち 𝑖
勤務条件を表す制約式の例
金曜日の昼はスキルAを持った人が1人以上いなくてはならない
𝑤𝑖𝑗𝑘
スタッフ𝑗
日にち 𝑖
昼に勤務しているシフト
勤務条件を表す制約式の例
金曜日の昼はスキルAを持った人が1人以上いなくてはならない
𝑤𝑖𝑗𝑘
スタッフ𝑗
日にち 𝑖
勤務条件を表す制約式の例
金曜日の昼はスキルAを持った人が1人以上いなくてはならない
෍ ≥ 1
勤務条件を表す制約式の例
金曜日の昼はスキルAを持った人が1人以上いなくてはならない
必要人数と勤務人数のGap最小化
9:00 15:00 21:00
オーバースタッフ
(余剰時間)
アンダースタッフ
(不足時間)
必要人員数 実際の勤務人数
目標関数:ペナルティの合計を最小化
必要人員数と割当てた
スタッフ数の差(Gap)を
最小化
働きやすい勤務の
組み合わせなどの
違反回数の合計を最小化
シフト割り当て回数の公平化
勤務人数の平準化
勤務効率 働きやすさ 公平性
 
i h
ij MaximumNdPenaltycPenaltybGapaMinimize ...21:
a, b. c, d… は評価の重み係数
本日の内容
1
• 最適化問題とは何か
2
• 応用分野と勤務スケジューリング問題
3
• なぜRubyを使うのか
2.x
3.x
1.x オンプレミス SaaS
2007年 2008年 2009年 2010年 2011年 2012年 2013年 2014年 2015年 2016年
4.x
Web ASP ➠ Ruby on Rails ➠
最適化 C++ ➠ JRuby ➠
WINWORKS One の歴史
なぜRubyを使うのか
require 'gurobi‘
model = Gurobi::Model.new
x = model.add_var(vtype: :integer)
y = model.add_var(vtype: :integer)
model.maximize x * 2 + y * 3
model.add_constr x + y * 2 <= 12
model.add_constr x * 3 + y * 2 <= 18
model.optimize
最適化の式をわかりやすい形でコード上で表現できる
なぜRubyを使うのか
import gurobi.GRB;
import gurobi.GRBEnv;
import gurobi.GRBException;
import gurobi.GRBLinExpr;
import gurobi.GRBModel;
import gurobi.GRBVar;
public class ProductionPlanning {
public static void main(String[] args) throws GRBException {
GRBEnv env = new GRBEnv();
GRBModel model = new GRBModel(env);
GRBVar x = model.addVar(0.0, GRB.INFINITY, 0.0, GRB.INTEGER, null);
GRBVar y = model.addVar(0.0, GRB.INFINITY, 0.0, GRB.INTEGER, null);
model.update();
// miximize: 2x + 3y
GRBLinExpr expr = new GRBLinExpr();
expr.addTerm(2, x);
expr.addTerm(3, y);
model.setObjective(expr, GRB.MAXIMIZE);
// x + 2y <= 12
expr = new GRBLinExpr();
expr.addTerm(1, x);
expr.addTerm(2, y);
model.addConstr(expr, GRB.LESS_EQUAL, 12, null);
// 3x + 2y <= 18
expr = new GRBLinExpr();
expr.addTerm(3, x);
expr.addTerm(2, y);
model.addConstr(expr, GRB.LESS_EQUAL, 18, null);
model.update();
model.optimize();
}
require 'gurobi‘
model = Gurobi::Model.new
x = model.add_var(vtype: :integer)
y = model.add_var(vtype: :integer)
model.maximize x * 2 + y * 3
model.add_constr x + y * 2 <= 12
model.add_constr x * 3 + y * 2 <= 18
model.optimize
最適化の式をわかりやすい形でコード上で表現できる
なぜRubyを使うのか
Webアプリケーション部分との使用言語の統一
本日の内容
1
• 最適化問題とは何か
2
• 応用分野と勤務スケジューリング問題
3
• なぜRubyを使うのか
最後に

More Related Content

What's hot

解説!30分で分かるLEAN ANALYTICS
解説!30分で分かるLEAN ANALYTICS解説!30分で分かるLEAN ANALYTICS
解説!30分で分かるLEAN ANALYTICSしくみ製作所
 
チケットファーストでアジャイル開発!~チケットに分割して統治せよ
チケットファーストでアジャイル開発!~チケットに分割して統治せよチケットファーストでアジャイル開発!~チケットに分割して統治せよ
チケットファーストでアジャイル開発!~チケットに分割して統治せよakipii Oga
 
ソフトウェアの核心にある複雑さに立ち向かう
ソフトウェアの核心にある複雑さに立ち向かうソフトウェアの核心にある複雑さに立ち向かう
ソフトウェアの核心にある複雑さに立ち向かう増田 亨
 
ソフトウェア開発のやり方の改善
ソフトウェア開発のやり方の改善ソフトウェア開発のやり方の改善
ソフトウェア開発のやり方の改善増田 亨
 
リクルートが実践で学んできた“セルフBI”推進に求められる3つの要素
リクルートが実践で学んできた“セルフBI”推進に求められる3つの要素リクルートが実践で学んできた“セルフBI”推進に求められる3つの要素
リクルートが実践で学んできた“セルフBI”推進に求められる3つの要素Recruit Technologies
 
営業さんまで、社員全員がSQLを使う 「越境型組織」 ができるまでの3+1のポイント | リブセンス
営業さんまで、社員全員がSQLを使う 「越境型組織」 ができるまでの3+1のポイント | リブセンス営業さんまで、社員全員がSQLを使う 「越境型組織」 ができるまでの3+1のポイント | リブセンス
営業さんまで、社員全員がSQLを使う 「越境型組織」 ができるまでの3+1のポイント | リブセンスLivesense Inc.
 
ドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみようドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみよう増田 亨
 
ドメイン駆動設計 コアドメインを語り合ってみよう
ドメイン駆動設計 コアドメインを語り合ってみようドメイン駆動設計 コアドメインを語り合ってみよう
ドメイン駆動設計 コアドメインを語り合ってみよう増田 亨
 
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかDDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかKoichiro Matsuoka
 
Humble Object Patternな話
Humble Object Patternな話Humble Object Patternな話
Humble Object Patternな話Hiroto Imoto
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方増田 亨
 
クラシフィケーション・ツリー法入門
クラシフィケーション・ツリー法入門クラシフィケーション・ツリー法入門
クラシフィケーション・ツリー法入門H Iseri
 
大規模な組合せ最適化問題に対する発見的解法
大規模な組合せ最適化問題に対する発見的解法大規模な組合せ最適化問題に対する発見的解法
大規模な組合せ最適化問題に対する発見的解法Shunji Umetani
 
べき乗則・パレート分布・ジップの法則
べき乗則・パレート分布・ジップの法則べき乗則・パレート分布・ジップの法則
べき乗則・パレート分布・ジップの法則Hiroyuki Kuromiya
 
結果的に組織がAgileな状態であること #agile #scrum #leanstartup
結果的に組織がAgileな状態であること #agile #scrum #leanstartup結果的に組織がAgileな状態であること #agile #scrum #leanstartup
結果的に組織がAgileな状態であること #agile #scrum #leanstartupItsuki Kuroda
 
ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説増田 亨
 
ドメイン駆動設計に15年取り組んでわかったこと
ドメイン駆動設計に15年取り組んでわかったことドメイン駆動設計に15年取り組んでわかったこと
ドメイン駆動設計に15年取り組んでわかったこと増田 亨
 
最適化超入門
最適化超入門最適化超入門
最適化超入門Takami Sato
 
画像認識の初歩、SIFT,SURF特徴量
画像認識の初歩、SIFT,SURF特徴量画像認識の初歩、SIFT,SURF特徴量
画像認識の初歩、SIFT,SURF特徴量takaya imai
 
大企業アジャイルの勘所(ver1.1) #アジャイルマネジメントセミナー
大企業アジャイルの勘所(ver1.1) #アジャイルマネジメントセミナー大企業アジャイルの勘所(ver1.1) #アジャイルマネジメントセミナー
大企業アジャイルの勘所(ver1.1) #アジャイルマネジメントセミナーItsuki Kuroda
 

What's hot (20)

解説!30分で分かるLEAN ANALYTICS
解説!30分で分かるLEAN ANALYTICS解説!30分で分かるLEAN ANALYTICS
解説!30分で分かるLEAN ANALYTICS
 
チケットファーストでアジャイル開発!~チケットに分割して統治せよ
チケットファーストでアジャイル開発!~チケットに分割して統治せよチケットファーストでアジャイル開発!~チケットに分割して統治せよ
チケットファーストでアジャイル開発!~チケットに分割して統治せよ
 
ソフトウェアの核心にある複雑さに立ち向かう
ソフトウェアの核心にある複雑さに立ち向かうソフトウェアの核心にある複雑さに立ち向かう
ソフトウェアの核心にある複雑さに立ち向かう
 
ソフトウェア開発のやり方の改善
ソフトウェア開発のやり方の改善ソフトウェア開発のやり方の改善
ソフトウェア開発のやり方の改善
 
リクルートが実践で学んできた“セルフBI”推進に求められる3つの要素
リクルートが実践で学んできた“セルフBI”推進に求められる3つの要素リクルートが実践で学んできた“セルフBI”推進に求められる3つの要素
リクルートが実践で学んできた“セルフBI”推進に求められる3つの要素
 
営業さんまで、社員全員がSQLを使う 「越境型組織」 ができるまでの3+1のポイント | リブセンス
営業さんまで、社員全員がSQLを使う 「越境型組織」 ができるまでの3+1のポイント | リブセンス営業さんまで、社員全員がSQLを使う 「越境型組織」 ができるまでの3+1のポイント | リブセンス
営業さんまで、社員全員がSQLを使う 「越境型組織」 ができるまでの3+1のポイント | リブセンス
 
ドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみようドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみよう
 
ドメイン駆動設計 コアドメインを語り合ってみよう
ドメイン駆動設計 コアドメインを語り合ってみようドメイン駆動設計 コアドメインを語り合ってみよう
ドメイン駆動設計 コアドメインを語り合ってみよう
 
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかDDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
 
Humble Object Patternな話
Humble Object Patternな話Humble Object Patternな話
Humble Object Patternな話
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方
 
クラシフィケーション・ツリー法入門
クラシフィケーション・ツリー法入門クラシフィケーション・ツリー法入門
クラシフィケーション・ツリー法入門
 
大規模な組合せ最適化問題に対する発見的解法
大規模な組合せ最適化問題に対する発見的解法大規模な組合せ最適化問題に対する発見的解法
大規模な組合せ最適化問題に対する発見的解法
 
べき乗則・パレート分布・ジップの法則
べき乗則・パレート分布・ジップの法則べき乗則・パレート分布・ジップの法則
べき乗則・パレート分布・ジップの法則
 
結果的に組織がAgileな状態であること #agile #scrum #leanstartup
結果的に組織がAgileな状態であること #agile #scrum #leanstartup結果的に組織がAgileな状態であること #agile #scrum #leanstartup
結果的に組織がAgileな状態であること #agile #scrum #leanstartup
 
ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説
 
ドメイン駆動設計に15年取り組んでわかったこと
ドメイン駆動設計に15年取り組んでわかったことドメイン駆動設計に15年取り組んでわかったこと
ドメイン駆動設計に15年取り組んでわかったこと
 
最適化超入門
最適化超入門最適化超入門
最適化超入門
 
画像認識の初歩、SIFT,SURF特徴量
画像認識の初歩、SIFT,SURF特徴量画像認識の初歩、SIFT,SURF特徴量
画像認識の初歩、SIFT,SURF特徴量
 
大企業アジャイルの勘所(ver1.1) #アジャイルマネジメントセミナー
大企業アジャイルの勘所(ver1.1) #アジャイルマネジメントセミナー大企業アジャイルの勘所(ver1.1) #アジャイルマネジメントセミナー
大企業アジャイルの勘所(ver1.1) #アジャイルマネジメントセミナー
 

Rubyによる組合せ最適化