わんくま同盟 名古屋勉強会 #37...

52
わんくま同盟 名古屋勉強会 #37 ソルバーで 組み合わせ問題を 解いて遊ぶ H.Hiro http://hhiro.net/ Twitter: @h_hiro_

Upload: hiro-h

Post on 11-Apr-2017

505 views

Category:

Technology


5 download

TRANSCRIPT

Page 1: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

ソルバーで

組み合わせ問題を

解いて遊ぶ

H.Hiro

http://hhiro.net/

Twitter: @h_hiro_

Page 2: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

自己紹介

Page 3: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

H.Hiro

• 情報系の某研究員です。

• 昨年度まで札幌に住んでました。

• 趣味プログラミング19年目です。

現在はRubyやC++を多用します。

Page 4: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

サンプル

プログラム等は

こちらにあります http://hhiro.net/wkn37

Page 5: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

今回行うこと

Page 6: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

• いろいろな「組み合わせ」をコンピュータに

試させる

Page 7: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

手当たり次第に

候補を探すには

時間がかかりすぎる

Page 8: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

• 普通に解こうとすると時間がかかるが

需要がある問題なわけなので

「何とかしたい!」と思う人はたくさんいる

• となると、効率よく解くために努力している

人もたくさんいる

• そういった方々の努力の産物(ソルバー)に、

ありがたく乗っからせていただこう

Page 9: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

ソルバー

• 英語 “solver” の意味からすれば

(問題を)解くためのもの

• 一般的にソルバーといえば:事前に定められた

フォーマットに該当する問題について、それを

指定すると解いてくれるもの

–例えば

「●●の形の方程式を解いてくれる」とか

「●●の形の式を最大化するものを

見つける」とか

Page 10: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

Excelのソルバーを見てみる

有効化する方法(MS Office 2007の場合)

• 左上のOfficeアイコン

• →「Excelのオプション」

• →「アドイン」

• →「設定」

Page 11: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

Excelのソルバーを見てみる

Page 12: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

Excelのソルバーを見てみる

Page 13: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

• とりあえず、値を「最大化」「最小化」 「特定の値にする」ような計算はできることが

わかった

• ただ、「解きたい問題をExcelのソルバーが

解ける形に変換する」とか、これだと効率的に

解けない問題とかもあるし

• 問題によっては、Excelとは違うソルバーに

任せるべきこともあるし

• 話は単純じゃない

Page 14: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

今回やること

• ソルバーを使う際の考え方、すなわち

– 「どんな問題なら解けるのか」

– 「どんな形で問題を与えてあげれば、

望む問題を解いてもらえるか」

を中心に説明します。

• 極力「汎用性の高いソルバー」を紹介します。

• ソルバーの中身までは説明しません。

• 数学的な説明も少し入ります。

Page 15: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

今回取り扱う問題

Page 16: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

1. 一つでも組み合わせが見つかればよい問題

2. 条件を満たすものの中で最適な結果を

得たい問題

3. すべての可能性を列挙したい問題

Page 17: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

の前に

一つだけ

大事な補足

Page 18: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

• ここから扱う問題は、主に

「一般には理論的には、計算時間が

爆発するとわかっている問題」を扱います。

(「NP完全」とか「NP困難」とかそれ以上)

• ただ、組み合わせ系の問題が全部それに

該当するわけじゃないです。

Page 19: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

例:ある地点からある地点への最短経路

スタ

ート

ゴー

これは、あとで扱う問題に比べれば

「問題サイズの増加に対する計算時間の増加」は

非常に小さい!(「ダイクストラ法」という方法がある。

計算時間は高々、地点数の2乗でしか増えない)

Page 20: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

例:ある地点からある地点への最短経路

スタ

ート

ゴー

(時間のかかるような)ソルバーに頼るのは

最後の手段と考えておこう。

問題が大きくなると時間がかかりすぎて解けない。

Page 21: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

1.

「一つでも組み合わせが

見つかればよい問題」 を解く

Page 22: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

「一つでも組み合わせが見つかればよい問題」

が想定される状況:

• ある計画が実行可能であるか

わからないとき、それを確かめたい

• お絵かきロジック(ピクロス)、

数独等のパズル(多くの場合、

問題を作る際に二つ以上の

答えが出ないようにしている)

Page 23: わんくま同盟 名古屋勉強会 #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

(充足可能性問題)から

Page 24: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #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

Page 25: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

• 例えば数独を解く場合

Page 26: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

• 例えば数独を解く場合

各マスには1から9の数字を入れる。

しかし、論理式の変数一つ一つは真偽値。

• なので、「マスAに1が入る」「マスAに2が入る」 …「マスAに9が入る」という真偽値をそれぞれ

用意する。 参考:http://d.hatena.ne.jp/ku-ma-me/20080108/p1

真偽値だけで条件を書ければ、解いてもらえる

※もちろん、変数が増えると遅くなる

Page 27: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

“[このマスは4] or [このマスは7] or

[このマスは9]” という式を書く

• 縦の制約:1, 2は不可

• 横の制約:1, 2, 3, 5, 8は不可

• 3×3正方形の制約:1, 2, 3, 6は不可

Page 28: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

• 真偽値だけで全部条件を書こうとすると

大変だったもの:お絵かきロジック(ピクロス)

Page 29: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

• 真偽値だけで全部条件を書こうとすると

大変だったもの:お絵かきロジック(ピクロス)

例えばこの列を表現しようとすると

「全部の可能性を列挙するしかない」。

• [あ]と[う]は塗る、他は塗らない

• [あ]と[え]は塗る、他は塗らない

• [あ]と[お]は塗る、他は塗らない

• [い]と[え]は塗る、他は塗らない

• [い]と[お]は塗る、他は塗らない

• [う]と[お]は塗る、他は塗らない う え お あ い

•論理式では、「個数」は

扱いにくい

•マス数が増えるともっと大変

Page 30: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

この節のまとめ

• 「一つでも組み合わせが見つかればよい問題」 を考えた

• SATソルバーを使うのが一つの手段

• SATソルバーは、問題を適切な数の論理式で

表現できるなら使ってみるとよいだろう

Page 31: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

2.

「条件を満たすものの

中で、最適な結果を

得たい問題」 を解く

Page 32: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

「条件を満たすものの中で、最適な結果を

得たい問題」が想定される状況:

• 最短(最長)の経路を求めたい、

最大の利益(または最小のコスト)となる

組み合わせを求めたい、など

• 「地域内のすべての家(または道路)を

検査して回る最短経路」など

Page 33: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

さっきの「ある地点からある地点への最短経路」

は比較的容易に解ける問題ということだったので

もっと難しい問題を扱います。

スタ

ート

ゴー

Page 34: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

• 例:「最大単語数でのしりとり」 (事前に与えられた単語集合をなるべく多く

利用し、しりとりになるようにする) http://nlab.itmedia.co.jp/nl/articles/1107/19/news080.html

http://chiraura.hhiro.net/shiritori/

Page 35: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

• 例:「最長片道切符」 (JRの切符として買える

最長のものを求める。

「同じ駅を二度通ったら

それ以上進めない」と

いう制約がある) http://www.swa.gr.jp/lop/

Page 36: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

「条件を満たすものの中で、最適な結果を得たい

問題」を解くソルバーの例:線形計画ソルバー

• 線形の式(定数×変数+定数×変数+…)で

条件式ならびに最大化したい式を書く。

• それを最大化するものを返してくれる。

• Excelのソルバーの一つにこれが入っている

例:

制約条件 2x + y ≦ 100, x + 2y ≦ 140 のもとで、

x + y の最大値は?

Page 37: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

• 高校数学で出てくる問題です

例:

制約条件 2x + y ≦ 100, x + 2y ≦ 140 のもとで、

x + y の最大値は?

x

y

140

100

2x + y ≦ 100 を満たす範囲

x + 2y ≦ 140 を満たす範囲

実際に x, y が存在できる範囲

50

70

Page 38: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #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 の最大値はこれ!

Page 39: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

• 高校数学で出てくる問題です

例:

制約条件 2x + y ≦ 100, x + 2y ≦ 140 のもとで、

x + y の最大値は?

x

y

70

140

100

50

• これを、変数や条件の数が

増えてもちゃんと解いてくれるのが

線形計画ソルバー

Page 40: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

• で、しりとりや鉄道路線の問題って線形の式で

書けるの?

• 書けるには書けるけど、完全ではない

制約条件: 1. [X で始まって Y で終わる単語数]は0以上Z以下

(与えられた単語の総数) 2. ΣX [“あ”で始まって X で終わる単語数]

= ΣY [Y で始まって“あ”で終わる単語数]

(しりとりになる条件) ※最初・最後の単語は別扱いが必要 ※“あ”以外も同様

最大化したい式: ΣX, Y [X で始まって Y で終わる単語数]

「単語数」は

整数。

でも

さっきの方法

だと答えが

小数になりうる

Page 41: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

• 線形計画問題の、変数の値を整数に

限定したもの(整数計画問題)は、

単なる線形計画問題に比べて大幅に遅い

• ただ、それでも変数や条件が極端に多く

なければ解いてくれる

Page 42: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

線形計画問題・整数計画問題を解いてくれる

ソルバーの例:

• Excelのソルバー

(変数は整数に限る、という指定もできる)

• GLPK https://www.gnu.org/software/glpk/

(オープンソース、私の実装でも利用)

Page 43: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

補足:Excelのソルバーで「変数は整数に限る」

という指定をする方法

Page 44: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

例題(Excelファイル参照)

制約条件 2x + y ≦ 100, x + 2y ≦ 130 のもとで、

x + y の最大値は?

(さっきと微妙に値が違う。きれいな値にはならない)

制約条件 2x + y ≦ 100, x + 2y ≦ 130 のもとで、

x + y の最大値は?(ただしx, yは整数に限る)

Page 45: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

3.

「すべての可能性を

列挙したい問題」 を解く

Page 46: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

「すべての可能性を列挙したい問題」が

想定される状況:

• 実際にどの結果を採用するか、人の目で見て

判断したい

• 例えば、最短経路以外も見つけておいて

実際によさそうなものを選ぶ

Page 47: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

「すべての可能性を列挙したい問題」の難しい

ところは、その結果も巨大になりうること。

結果を適切に圧縮して出力・保持できることを

想定する。

Page 48: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

「すべての可能性を列挙したい問題」を解く

ソルバー(どちらかといえば、すべての可能性を

効率よく表現するライブラリ)の例:Graphillion https://github.com/takemaru/graphillion/wiki

• グラフ構造を対象に、条件を満たすものを

すべて列挙する

• 参考:「おねえさんが経路数を数え上げる動画」 https://youtu.be/Q4gTV4r0zRs

これの技術的バックグラウンド

Page 49: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

左上から右下への「同じ点を二度

通らない」行き方:2通り

左上から右下への「同じ点を二度

通らない」行き方:12通り

左上から右下への「同じ点を二度

通らない」行き方:184通り

https://youtu.be/Q4gTV4r0zRs

Page 50: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

Graphillionの技術的な特徴:

“ZDD”という「集合の集合」を圧縮表現する

データ構造を用いている

• 扱う対象が集合として書ければ、

ZDDで表現できるので、グラフ構造以外でも

表現を圧縮できる可能性はある

• ただし、それが効率よく表現できる(圧縮率が

高い)かは、その集合の性質に依存する

(サイズが爆発する場合もある)

Page 51: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

おわりに

Page 52: わんくま同盟 名古屋勉強会 #37 「ソルバーで組み合わせ問題を解いて遊ぶ」

わんくま同盟 名古屋勉強会 #37

多くの組み合わせを調べたいときは、先人の

知恵の詰まったソルバーに頼ってみよう。

• ただし、それがなくても十分高速に

解けるかもしれないことは留意を。

• 頼っても解けない場合もあることにも留意を。

• うまく解いてもらうには、問題の特徴を

押さえたり、問題を変形してあげないと

ならない。