わんくま同盟 名古屋勉強会 #37...
TRANSCRIPT
わんくま同盟 名古屋勉強会 #37
ソルバーで
組み合わせ問題を
解いて遊ぶ
H.Hiro
http://hhiro.net/
Twitter: @h_hiro_
わんくま同盟 名古屋勉強会 #37
自己紹介
わんくま同盟 名古屋勉強会 #37
H.Hiro
• 情報系の某研究員です。
• 昨年度まで札幌に住んでました。
• 趣味プログラミング19年目です。
現在はRubyやC++を多用します。
わんくま同盟 名古屋勉強会 #37
今回行うこと
わんくま同盟 名古屋勉強会 #37
• いろいろな「組み合わせ」をコンピュータに
試させる
わんくま同盟 名古屋勉強会 #37
手当たり次第に
候補を探すには
時間がかかりすぎる
わんくま同盟 名古屋勉強会 #37
• 普通に解こうとすると時間がかかるが
需要がある問題なわけなので
「何とかしたい!」と思う人はたくさんいる
• となると、効率よく解くために努力している
人もたくさんいる
• そういった方々の努力の産物(ソルバー)に、
ありがたく乗っからせていただこう
わんくま同盟 名古屋勉強会 #37
ソルバー
• 英語 “solver” の意味からすれば
(問題を)解くためのもの
• 一般的にソルバーといえば:事前に定められた
フォーマットに該当する問題について、それを
指定すると解いてくれるもの
–例えば
「●●の形の方程式を解いてくれる」とか
「●●の形の式を最大化するものを
見つける」とか
わんくま同盟 名古屋勉強会 #37
Excelのソルバーを見てみる
有効化する方法(MS Office 2007の場合)
• 左上のOfficeアイコン
• →「Excelのオプション」
• →「アドイン」
• →「設定」
わんくま同盟 名古屋勉強会 #37
Excelのソルバーを見てみる
わんくま同盟 名古屋勉強会 #37
Excelのソルバーを見てみる
わんくま同盟 名古屋勉強会 #37
• とりあえず、値を「最大化」「最小化」 「特定の値にする」ような計算はできることが
わかった
• ただ、「解きたい問題をExcelのソルバーが
解ける形に変換する」とか、これだと効率的に
解けない問題とかもあるし
• 問題によっては、Excelとは違うソルバーに
任せるべきこともあるし
• 話は単純じゃない
わんくま同盟 名古屋勉強会 #37
今回やること
• ソルバーを使う際の考え方、すなわち
– 「どんな問題なら解けるのか」
– 「どんな形で問題を与えてあげれば、
望む問題を解いてもらえるか」
を中心に説明します。
• 極力「汎用性の高いソルバー」を紹介します。
• ソルバーの中身までは説明しません。
• 数学的な説明も少し入ります。
わんくま同盟 名古屋勉強会 #37
今回取り扱う問題
わんくま同盟 名古屋勉強会 #37
1. 一つでも組み合わせが見つかればよい問題
2. 条件を満たすものの中で最適な結果を
得たい問題
3. すべての可能性を列挙したい問題
わんくま同盟 名古屋勉強会 #37
の前に
一つだけ
大事な補足
わんくま同盟 名古屋勉強会 #37
• ここから扱う問題は、主に
「一般には理論的には、計算時間が
爆発するとわかっている問題」を扱います。
(「NP完全」とか「NP困難」とかそれ以上)
• ただ、組み合わせ系の問題が全部それに
該当するわけじゃないです。
わんくま同盟 名古屋勉強会 #37
例:ある地点からある地点への最短経路
スタ
ート
ゴー
ル
これは、あとで扱う問題に比べれば
「問題サイズの増加に対する計算時間の増加」は
非常に小さい!(「ダイクストラ法」という方法がある。
計算時間は高々、地点数の2乗でしか増えない)
わんくま同盟 名古屋勉強会 #37
例:ある地点からある地点への最短経路
スタ
ート
ゴー
ル
(時間のかかるような)ソルバーに頼るのは
最後の手段と考えておこう。
問題が大きくなると時間がかかりすぎて解けない。
わんくま同盟 名古屋勉強会 #37
1.
「一つでも組み合わせが
見つかればよい問題」 を解く
わんくま同盟 名古屋勉強会 #37
「一つでも組み合わせが見つかればよい問題」
が想定される状況:
• ある計画が実行可能であるか
わからないとき、それを確かめたい
• お絵かきロジック(ピクロス)、
数独等のパズル(多くの場合、
問題を作る際に二つ以上の
答えが出ないようにしている)
わんくま同盟 名古屋勉強会 #37
「一つでも組み合わせが見つかればよい問題」
を解くソルバーの例:SATソルバー
• 論理式を入力する。
• それを満たす真/偽の組み合わせがあれば
一つ返す。なければ「ない」と答える。
例:
A, B, Cが真理値(「真」か「偽」を取る)のとき
[A or B] and [(not A) or C] and [(not B) or (not C)]
が真になるA, B, Cの組み合わせは存在する?
Satisfiability Problem
(充足可能性問題)から
わんくま同盟 名古屋勉強会 #37
• ソフトウェア多数
• ただ、Excel標準のソルバーでは解けない(?)
• ここでは「minisat」の例を示す http://minisat.se/
※Windowsではcygwinが必要(mingwでは不可)
[A or B] and [(not A) or C] and [(not B) or (not C)]
p cnf 3 3 /* “3変数・式3行”の意味 */
1 2 0 /* 0が1つの式の終わり */
-1 3 0 /* マイナスはnotの意味 */
-2 -3 0
↓ “dimacs”というフォーマットで記述(上記のような “[… or …] and …” の形の式に特化)
→
解かせる
SAT /* 組み合わせあり */
-1 2 -3 0
わんくま同盟 名古屋勉強会 #37
• 例えば数独を解く場合
わんくま同盟 名古屋勉強会 #37
• 例えば数独を解く場合
各マスには1から9の数字を入れる。
しかし、論理式の変数一つ一つは真偽値。
• なので、「マスAに1が入る」「マスAに2が入る」 …「マスAに9が入る」という真偽値をそれぞれ
用意する。 参考:http://d.hatena.ne.jp/ku-ma-me/20080108/p1
真偽値だけで条件を書ければ、解いてもらえる
※もちろん、変数が増えると遅くなる
わんくま同盟 名古屋勉強会 #37
“[このマスは4] or [このマスは7] or
[このマスは9]” という式を書く
• 縦の制約:1, 2は不可
• 横の制約:1, 2, 3, 5, 8は不可
• 3×3正方形の制約:1, 2, 3, 6は不可
わんくま同盟 名古屋勉強会 #37
• 真偽値だけで全部条件を書こうとすると
大変だったもの:お絵かきロジック(ピクロス)
わんくま同盟 名古屋勉強会 #37
• 真偽値だけで全部条件を書こうとすると
大変だったもの:お絵かきロジック(ピクロス)
例えばこの列を表現しようとすると
「全部の可能性を列挙するしかない」。
• [あ]と[う]は塗る、他は塗らない
• [あ]と[え]は塗る、他は塗らない
• [あ]と[お]は塗る、他は塗らない
• [い]と[え]は塗る、他は塗らない
• [い]と[お]は塗る、他は塗らない
• [う]と[お]は塗る、他は塗らない う え お あ い
•論理式では、「個数」は
扱いにくい
•マス数が増えるともっと大変
わんくま同盟 名古屋勉強会 #37
この節のまとめ
• 「一つでも組み合わせが見つかればよい問題」 を考えた
• SATソルバーを使うのが一つの手段
• SATソルバーは、問題を適切な数の論理式で
表現できるなら使ってみるとよいだろう
わんくま同盟 名古屋勉強会 #37
2.
「条件を満たすものの
中で、最適な結果を
得たい問題」 を解く
わんくま同盟 名古屋勉強会 #37
「条件を満たすものの中で、最適な結果を
得たい問題」が想定される状況:
• 最短(最長)の経路を求めたい、
最大の利益(または最小のコスト)となる
組み合わせを求めたい、など
• 「地域内のすべての家(または道路)を
検査して回る最短経路」など
わんくま同盟 名古屋勉強会 #37
さっきの「ある地点からある地点への最短経路」
は比較的容易に解ける問題ということだったので
もっと難しい問題を扱います。
スタ
ート
ゴー
ル
わんくま同盟 名古屋勉強会 #37
• 例:「最大単語数でのしりとり」 (事前に与えられた単語集合をなるべく多く
利用し、しりとりになるようにする) http://nlab.itmedia.co.jp/nl/articles/1107/19/news080.html
http://chiraura.hhiro.net/shiritori/
わんくま同盟 名古屋勉強会 #37
• 例:「最長片道切符」 (JRの切符として買える
最長のものを求める。
「同じ駅を二度通ったら
それ以上進めない」と
いう制約がある) http://www.swa.gr.jp/lop/
わんくま同盟 名古屋勉強会 #37
「条件を満たすものの中で、最適な結果を得たい
問題」を解くソルバーの例:線形計画ソルバー
• 線形の式(定数×変数+定数×変数+…)で
条件式ならびに最大化したい式を書く。
• それを最大化するものを返してくれる。
• Excelのソルバーの一つにこれが入っている
例:
制約条件 2x + y ≦ 100, x + 2y ≦ 140 のもとで、
x + y の最大値は?
わんくま同盟 名古屋勉強会 #37
• 高校数学で出てくる問題です
例:
制約条件 2x + y ≦ 100, x + 2y ≦ 140 のもとで、
x + y の最大値は?
x
y
140
100
2x + y ≦ 100 を満たす範囲
x + 2y ≦ 140 を満たす範囲
実際に x, y が存在できる範囲
50
70
わんくま同盟 名古屋勉強会 #37
• 高校数学で出てくる問題です
例:
制約条件 2x + y ≦ 100, x + 2y ≦ 140 のもとで、
x + y の最大値は?
x
y
140
100
50
70
x + y = 20 である箇所の集合
x + y = 50 である箇所の集合
x + y = 80 である箇所の集合
→ x + y の最大値はこれ!
わんくま同盟 名古屋勉強会 #37
• 高校数学で出てくる問題です
例:
制約条件 2x + y ≦ 100, x + 2y ≦ 140 のもとで、
x + y の最大値は?
x
y
70
140
100
50
• これを、変数や条件の数が
増えてもちゃんと解いてくれるのが
線形計画ソルバー
わんくま同盟 名古屋勉強会 #37
• で、しりとりや鉄道路線の問題って線形の式で
書けるの?
• 書けるには書けるけど、完全ではない
制約条件: 1. [X で始まって Y で終わる単語数]は0以上Z以下
(与えられた単語の総数) 2. ΣX [“あ”で始まって X で終わる単語数]
= ΣY [Y で始まって“あ”で終わる単語数]
(しりとりになる条件) ※最初・最後の単語は別扱いが必要 ※“あ”以外も同様
最大化したい式: ΣX, Y [X で始まって Y で終わる単語数]
「単語数」は
整数。
でも
さっきの方法
だと答えが
小数になりうる
わんくま同盟 名古屋勉強会 #37
• 線形計画問題の、変数の値を整数に
限定したもの(整数計画問題)は、
単なる線形計画問題に比べて大幅に遅い
• ただ、それでも変数や条件が極端に多く
なければ解いてくれる
わんくま同盟 名古屋勉強会 #37
線形計画問題・整数計画問題を解いてくれる
ソルバーの例:
• Excelのソルバー
(変数は整数に限る、という指定もできる)
• GLPK https://www.gnu.org/software/glpk/
(オープンソース、私の実装でも利用)
わんくま同盟 名古屋勉強会 #37
補足:Excelのソルバーで「変数は整数に限る」
という指定をする方法
わんくま同盟 名古屋勉強会 #37
例題(Excelファイル参照)
制約条件 2x + y ≦ 100, x + 2y ≦ 130 のもとで、
x + y の最大値は?
(さっきと微妙に値が違う。きれいな値にはならない)
制約条件 2x + y ≦ 100, x + 2y ≦ 130 のもとで、
x + y の最大値は?(ただしx, yは整数に限る)
わんくま同盟 名古屋勉強会 #37
3.
「すべての可能性を
列挙したい問題」 を解く
わんくま同盟 名古屋勉強会 #37
「すべての可能性を列挙したい問題」が
想定される状況:
• 実際にどの結果を採用するか、人の目で見て
判断したい
• 例えば、最短経路以外も見つけておいて
実際によさそうなものを選ぶ
わんくま同盟 名古屋勉強会 #37
「すべての可能性を列挙したい問題」の難しい
ところは、その結果も巨大になりうること。
結果を適切に圧縮して出力・保持できることを
想定する。
わんくま同盟 名古屋勉強会 #37
「すべての可能性を列挙したい問題」を解く
ソルバー(どちらかといえば、すべての可能性を
効率よく表現するライブラリ)の例:Graphillion https://github.com/takemaru/graphillion/wiki
• グラフ構造を対象に、条件を満たすものを
すべて列挙する
• 参考:「おねえさんが経路数を数え上げる動画」 https://youtu.be/Q4gTV4r0zRs
これの技術的バックグラウンド
わんくま同盟 名古屋勉強会 #37
左上から右下への「同じ点を二度
通らない」行き方:2通り
左上から右下への「同じ点を二度
通らない」行き方:12通り
左上から右下への「同じ点を二度
通らない」行き方:184通り
https://youtu.be/Q4gTV4r0zRs
わんくま同盟 名古屋勉強会 #37
Graphillionの技術的な特徴:
“ZDD”という「集合の集合」を圧縮表現する
データ構造を用いている
• 扱う対象が集合として書ければ、
ZDDで表現できるので、グラフ構造以外でも
表現を圧縮できる可能性はある
• ただし、それが効率よく表現できる(圧縮率が
高い)かは、その集合の性質に依存する
(サイズが爆発する場合もある)
わんくま同盟 名古屋勉強会 #37
おわりに
わんくま同盟 名古屋勉強会 #37
多くの組み合わせを調べたいときは、先人の
知恵の詰まったソルバーに頼ってみよう。
• ただし、それがなくても十分高速に
解けるかもしれないことは留意を。
• 頼っても解けない場合もあることにも留意を。
• うまく解いてもらうには、問題の特徴を
押さえたり、問題を変形してあげないと
ならない。