虫食算を作るアルゴリズム 公表Ver

Kensuke Otsuki
Kensuke OtsukiResearcher at NTT DATA MSI
虫食算を作るアルゴリズム
@drken1215
1 / 70
内容
• 作品紹介
• 虫食算を解くプログラム
– どの程度解ける ?
– DFSで解く
– (番外編) 整数計画法で解く
• 虫食算を作るプログラム
– 解くプログラムを改造
2 / 70
作品 1
• 7 つの 7 で 7 の形
ノ
3 / 70
作品 2
• 小町表出
4 / 70
作品 3
• おジャ魔女どれみ
– 1999~2003年放送
– 心温まるファミリーアニメ
OJA
MAJO
DOREMI
5 / 70
作品 4
6 / 70
作品 5
• いちご
黒丸の配置には意味があります
7 / 70
宣伝!!!
• 虫食算チャレンジサイトを作りました!
8 / 70
内容
• 作品紹介
• 虫食算を解くプログラム
– どの程度解ける ?
– DFSで解く
– (番外編) 整数計画法で解く
• 虫食算を作るプログラム
– 解くプログラムを改造
9 / 70
デモ
大駒誠一著 『虫食算パズル700選』 問 698
10 / 70
僅か 0.15 秒!!! (core i7, 4GB)
11 / 70
念のため…
• このプログラムを使えば簡単に虫食算を作れる
• しかし!!!
– 自動生成した虫食算が面白い問題とは限らない
– 解いて楽しい虫食算作りは職人のノウハウ
– ホームメイドの価値は健在
• ソフトは虫食算作りを支援するツール
12 / 70
内容
• 作品紹介
• 虫食算を解くプログラム
– どの程度解ける ?
– DFSで解く
– (番外編) 整数計画法で解く
• 虫食算を作るプログラム
– 解くプログラムを改造
13 / 70
最初に思いつく方法
• □への数字の当てはめを全通り試す
– 1054… 天文学的数字!
14 / 70
ちょっと工夫
• 上2段だけ全通り試す
– 1010 … 1時間程度で解けそう
15 / 70
ちょっと工夫
• 上2段だけ全通り試す
– 1010 … 1時間程度で解けそう
– しかし下のは 1043 通り!
16 / 70
も~っと!工夫
• 上2段を DFS
17 / 70
DFS (Depth First Search): 深さ優先探索
• □に数字を仮定して, 行けるところまで突き進む
• ダメになったら一歩戻る
18 / 70
DFS (Depth First Search): 深さ優先探索
• □に数字を仮定して, 行けるところまで突き進む
• ダメになったら一歩戻る
19 / 70
DFS (Depth First Search): 深さ優先探索
• □に数字を仮定して, 行けるところまで突き進む
• ダメになったら一歩戻る
20 / 70
DFS (Depth First Search): 深さ優先探索
• □に数字を仮定して, 行けるところまで突き進む
• ダメになったら一歩戻る
21 / 70
DFS (Depth First Search): 深さ優先探索
• □に数字を仮定して, 行けるところまで突き進む
• ダメになったら一歩戻る
… … 22 / 70
DFS (Depth First Search): 深さ優先探索
• □に数字を仮定して, 行けるところまで突き進む
• ダメになったら一歩戻る
… … 23 / 70
DFS (Depth First Search): 深さ優先探索
• □に数字を仮定して, 行けるところまで突き進む
• ダメになったら一歩戻る
… … 24 / 70
DFS (Depth First Search): 深さ優先探索
• □に数字を仮定して, 行けるところまで突き進む
• ダメになったら一歩戻る
… … 25 / 70
DFS (Depth First Search): 深さ優先探索
• □に数字を仮定して, 行けるところまで突き進む
• ダメになったら一歩戻る
… … 26 / 70
DFS (Depth First Search): 深さ優先探索
• □に数字を仮定して, 行けるところまで突き進む
• ダメになったら一歩戻る
… … 27 / 70
DFS (Depth First Search): 深さ優先探索
• □に数字を仮定して, 行けるところまで突き進む
• ダメになったら一歩戻る
… …
…
28 / 70
DFS (Depth First Search): 深さ優先探索
• □に数字を仮定して, 行けるところまで突き進む
• ダメになったら一歩戻る
… …
…
29 / 70
DFS (Depth First Search): 深さ優先探索
• □に数字を仮定して, 行けるところまで突き進む
• ダメになったら一歩戻る
… …
…
…
30 / 70
DFS (Depth First Search): 深さ優先探索
• □に数字を仮定して, 行けるところまで突き進む
• ダメになったら一歩戻る
DFS は応用範囲広い
 数独も解ける
 フリーセルも解ける
 ゲーム木探索も DFS の一種
 メモしながら探索すれば DP も実現
 実用性も: makefile (DAGのトポロジカルソート)
 ネットワークフローアルゴリズムのサブルーチン 31 / 70
DFS の工夫の余地
• □に数字を仮定して, 行けるところまで突き進む
• ダメになったら一歩戻る
• これでもうまくやらないとこれは解けない
32 / 70
DFS の工夫の余地
• □に数字を仮定して, 行けるところまで突き進む
• ダメになったら一歩戻る
• これでもうまくやらないとこれは解けない
どの□から順番に数字を仮定していくか
については、任意性がある!
33 / 70
さらに!!!探索順序を工夫!
• デタラメに DFS してもある程度は解けるが…
• 人間だったらどう解くかを考える!
34 / 70
人間だったらどう解くか…?
35 / 70
人間だったらどう解くか…?
• 一の位の 7 に目をつける
36 / 70
人間だったらどう解くか…?
• 青字の 7 が決まる
37 / 70
人間だったらどう解くか…?
• 十の位の 4 や 8 に目をつける
38 / 70
人間だったらどう解くか…?
• 桁数の情報も用いると、青字の部分が決まる
39 / 70
人間だったらどう解くか…?
• 百の位の 5 に目をつける
40 / 70
2 の次は
7 を探索
人間だったらどう解くか…?
• 青字の部分が 2 か 7 に決まる
……
41 / 70
2 の次は
7 を探索
人間だったらどう解くか…?
• 青字の部分が 2 か 7 に決まる
• まずは 2 を調べて、次に 7 を調べる
……
42 / 70
人間だったらどう解くか…?
• 一の位, 十の位, 百の位, … に数字のある段
を順々に着目する!
• この目の付け方の順序をプログラムする
43 / 70
工夫した探索順序による DFS
• For i = 1 to (Aの桁数):
– A の i 桁目を 0~9 の順に仮定
– For j = 1 to (Bの桁数):
• If C の j 段目の i 桁目に条件あり: B の j 桁目を 1~9 の順に仮定
• B のまだ仮定していない桁を 1~9 の順に仮定
□□□□□1
× □□□2□□
□3□□□□
□□□□□4□
□□□5□□
□□□6□□□
□□□□□7
□□□□□8□
□□□9□□□□□□□□
・・・ A
・・・ B
・・・ C
44 / 70
これであれが解ける!
• この探索順序を工夫した DFS (+ α の工夫)
で、超大型虫食算も解くことができた!
45 / 70
DFS による解法まとめ
• DFS (Depth First Search): 深さ優先探索
• DFS の探索順序を工夫する
• 探索順序を工夫した DFS により, 人間の思考
に近い虫食算ソルバーを実現!
46 / 70
発表の内容
• 作品紹介
• 虫食算を解くプログラム
– どの程度解ける ?
– DFSで解く
– (番外編) 整数計画法で解く
• 虫食算を作るプログラム
– 解くプログラムを改造
47 / 70
線形計画法 (LP) ->
• 一次式制約下で一次式最適化
Maximize:
4𝑥 + 5𝑦
Subject to:
3𝑥 + 2𝑦 ≤ 6
2𝑥 + 4𝑦 ≤ 8
𝑥, 𝑦 ≥ 0
𝑥
𝑦
O 42
2
3 (4, 5)
48 / 70
線形計画法 (LP) -> 整数計画法 (IP)
• 一次式制約下で一次式最適化
• 変数は整数値
Maximize:
4𝑥 + 5𝑦
Subject to:
3𝑥 + 2𝑦 ≤ 6
2𝑥 + 4𝑦 ≤ 8
𝑥, 𝑦 ≥ 0
𝑥, 𝑦 ∈ 𝒁 𝑥
𝑦
O 42
2
3 (4, 5)
49 / 70
IP を解く専用ソルバー
• 線形計画法 (LP) はカンタン
• 整数計画法 (IP) は超絶難しい (NP-hard)
• IP を解くソルバー達
– Numerical Optimizer (NTTデータ数理システム)
– CPLEX (IBM ILOG)
– XPRESS (FICO)
– Gurobi (Gurobi)
50 / 70
虫食算を IP で解く
• 虫食算を IP として定式化
• それをソルバーで解く
ここを紹介
51 / 70
Step 1: □と繰り上りを変数に
𝑐
𝑒 𝑑
𝑝𝑞
𝑎𝑏
52 / 70
Step 1: □と繰り上りを変数に
• 以下の整数計画問題に…?
3𝑐 = 10𝑝 + 7
𝑎𝑐 + 𝑝 = 10𝑞 + 𝑑
𝑏𝑐 + 𝑞 = 𝑒
0 ≤ 𝑎, 𝑑, 𝑝, 𝑞 ≤ 9
1 ≤ 𝑏, 𝑐, 𝑒 ≤ 9 𝑐
𝑒 𝑑
𝑝𝑞
𝑎𝑏
53 / 70
Step 1: □と繰り上りを変数に
• 以下の整数計画問題に…?
3𝑐 = 10𝑝 + 7
𝑎𝑐 + 𝑝 = 10𝑞 + 𝑑
𝑏𝑐 + 𝑞 = 𝑒
0 ≤ 𝑎, 𝑑, 𝑝, 𝑞 ≤ 9
1 ≤ 𝑏, 𝑐, 𝑒 ≤ 9
• ところが…!
• 二次項あり, IP じゃない!
𝑐
𝑒 𝑑
𝑝𝑞
𝑎𝑏
54 / 70
Step 1: □と繰り上りを変数に
• 以下の整数計画問題に…?
3𝑐 = 10𝑝 + 7
𝑎𝑐 + 𝑝 = 10𝑞 + 𝑑
𝑏𝑐 + 𝑞 = 𝑒
0 ≤ 𝑎, 𝑑, 𝑝, 𝑞 ≤ 9
1 ≤ 𝑏, 𝑐, 𝑒 ≤ 9
• ところが…!
• 二次項あり, IP じゃない!
• 0-1変数なら二次式制約を一次にできる (後述)
𝑐
𝑒 𝑑
𝑝𝑞
𝑎𝑏
55 / 70
Step 2: 各変数を二進法展開
• 以下の整数計画問題に…?
3𝑐 = 10𝑝 + 7
𝑎𝑐 + 𝑝 = 10𝑞 + 𝑑
𝑏𝑐 + 𝑞 = 𝑒
0 ≤ 𝑎, 𝑑, 𝑝, 𝑞 ≤ 9
1 ≤ 𝑏, 𝑐, 𝑒 ≤ 9
• 0-1変数 𝑎1, 𝑎2, 𝑎3, 𝑎4 を導入
𝑎 = 8𝑎1 + 4𝑎2 + 2𝑎3 + 𝑎4
𝑎1, 𝑎2, 𝑎3, 𝑎4 ∈ {0, 1}
𝑐
𝑒 𝑑
𝑝𝑞
𝑎𝑏
56 / 70
Step 2: 各変数を二進法展開
• この式は
𝑏𝑐 + 𝑞 = 𝑒
• こんな風になる
(8𝑏1 + 4𝑏2 + 2𝑏3 + 𝑏4)(8𝑐1 + 4𝑐2 + 2𝑐3 + 𝑐4) + 𝑞 = 𝑒
⇔
64𝑏1 𝑐1 + 32 𝑏1 𝑐2 + 𝑏2 𝑐1 + 16 𝑏1 𝑐3 + 𝑏2 𝑐2 + 𝑏3 𝑐1
+8 𝑏1 𝑐4 + 𝑏2 𝑐3 + 𝑏3 𝑐2 + 𝑏4 𝑐1 + 4 𝑏2 𝑐4 + 𝑏3 𝑐3 + 𝑏2 𝑐4
+2 𝑏3 𝑐4 + 𝑏4 𝑐3 + 𝑏4 𝑐4 + 𝑞 = 𝑒
57 / 70
Step 3: 0-1変数活用して一次式に
• 簡単のため, 以下の式を考える
𝑏1 𝑐1 + 𝑏2 𝑐2 + 𝑞 = 𝑒
58 / 70
Step 3: 0-1変数活用して一次式に
• 簡単のため, 以下の式を考える
𝑏1 𝑐1 + 𝑏2 𝑐2 + 𝑞 = 𝑒
• 𝑏1 𝑐1, 𝑏2 𝑐2 に対応する 0-1変数 𝑡1, 𝑡2 を導入
𝑏1 𝑐1 + 𝑏2 𝑐2 + 𝑞 = 𝑒
⇔
𝑡1 + 𝑡2 + 𝑞 = 𝑒
𝑡1 ≤ 𝑏1, 𝑡1 ≤ 𝑐1, 𝑡1 ≥ 𝑏1 + 𝑐1 − 1
𝑡2 ≤ 𝑏2, 𝑡2 ≤ 𝑐2, 𝑡2 ≥ 𝑏2 + 𝑐2 − 1
𝑏1 𝑐1 = 𝑡1 と等価
59 / 70
Step 3: 0-1変数活用して一次式に
• 簡単のため, 以下の式を考える
𝑏1 𝑐1 + 𝑏2 𝑐2 + 𝑞 = 𝑒
• 𝑏1 𝑐1, 𝑏2 𝑐2 に対応する 0-1変数 𝑡1, 𝑡2 を導入
𝑏1 𝑐1 + 𝑏2 𝑐2 + 𝑞 = 𝑒
⇔
𝑡1 + 𝑡2 + 𝑞 = 𝑒
𝑡1 ≤ 𝑏1, 𝑡1 ≤ 𝑐1, 𝑡1 ≥ 𝑏1 + 𝑐1 − 1
𝑡2 ≤ 𝑏2, 𝑡2 ≤ 𝑐2, 𝑡2 ≥ 𝑏2 + 𝑐2 − 1
𝑏1 𝑐1 = 𝑡1 と等価
一次式になった! 60 / 70
整数計画法 (IP) による解法まとめ
• やや大変だが, IP (一次式) にできる
3𝑐 = 10𝑝 + 7
𝑎𝑐 + 𝑝 = 10𝑞 + 𝑑
𝑏𝑐 + 𝑞 = 𝑒
0 ≤ 𝑎, 𝑑, 𝑝, 𝑞 ≤ 9
1 ≤ 𝑏, 𝑐, 𝑒 ≤ 9
• IP にしたら, IP ソルバーに投げる
• 6桁×6桁程度の虫食算ならこれで解けた
𝑐
𝑒 𝑑
𝑝𝑞
𝑎𝑏
61 / 70
発表の内容
• 作品紹介
• 虫食算を解くプログラム
– どの程度解ける ?
– DFSで解く
– (番外編) 整数計画法で解く
• 虫食算を作るプログラム
– 解くプログラムを改造
62 / 70
問題設定
• 数字, 文字の配置を固定
• 上二段の桁数も固定
• 一意解問題を作れ
63 / 70
作り方
• 青の部分は 0 でも OK として解く
• これで解なしならムリ
(掛ける数の桁数増やす)
• 何通りかの解を
青部分の様相で分類し
孤立したものを選ぶ
64 / 70
例
• 1, 2, 3 な虫食算を作ろう!
65 / 70
例
• 桁数無視で解くと, 9個の解!
66 / 70
例
• 桁数無視で解くと, 9個の解!
• 形が孤立しているものを選ぶと
67 / 70
例
• 桁数無視で解くと, 9個の解!
• 形が孤立しているものを選ぶと
– それぞれ 1 つの作品に
68 / 70
虫食算作るプログラム
• これだけで多くの場合作れる!
• 目安として1段に1個数字
がある程度が作りやすい
69 / 70
全体のまとめ
• 虫食算作りは楽しい
• コンピュータプログラムとコラボ
– 人間の目の付け所を優先的に探索する DFS
– 超爆速なソルバーが完成
• 虫食算を解くソフトをほんの少しの修正して、
虫食算作りもできる!
• ソフトは職人の虫食算制作を支援するツール
70 / 70
1 of 70

More Related Content

What's hot(20)

テストコードの DRY と DAMPテストコードの DRY と DAMP
テストコードの DRY と DAMP
Yusuke Kagata1.6K views
基礎線形代数講座基礎線形代数講座
基礎線形代数講座
SEGADevTech388.4K views
敵対的生成ネットワーク(GAN)敵対的生成ネットワーク(GAN)
敵対的生成ネットワーク(GAN)
cvpaper. challenge95.2K views
Pull Request & TDD 入門Pull Request & TDD 入門
Pull Request & TDD 入門
ESM SEC3.2K views
Crfと素性テンプレートCrfと素性テンプレート
Crfと素性テンプレート
Kei Uchiumi51.5K views
4 データ間の距離と類似度4 データ間の距離と類似度
4 データ間の距離と類似度
Seiichi Uchida3.6K views
深層学習の数理深層学習の数理
深層学習の数理
Taiji Suzuki79.7K views
深層学習による自然言語処理入門: word2vecからBERT, GPT-3まで深層学習による自然言語処理入門: word2vecからBERT, GPT-3まで
深層学習による自然言語処理入門: word2vecからBERT, GPT-3まで
Yahoo!デベロッパーネットワーク25.7K views

Similar to 虫食算を作るアルゴリズム 公表Ver(20)

PRML復々習レーン#10 7.1.3-7.1.5PRML復々習レーン#10 7.1.3-7.1.5
PRML復々習レーン#10 7.1.3-7.1.5
sleepy_yoshi2.8K views
魔女のお茶会.pdf魔女のお茶会.pdf
魔女のお茶会.pdf
Taikyaki 892630 views
witchs_key_party.pptxwitchs_key_party.pptx
witchs_key_party.pptx
Taikyaki 892646 views
AtCoder Beginner Contest 010 解説AtCoder Beginner Contest 010 解説
AtCoder Beginner Contest 010 解説
AtCoder Inc.11.1K views
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学
MITSUNARI Shigeo9.6K views
WUPC2012WUPC2012
WUPC2012
Dai Hamada1.6K views
深層学習を簡単に説明深層学習を簡単に説明
深層学習を簡単に説明
hirenjak M.982 views
第2回 メドレー読書会第2回 メドレー読書会
第2回 メドレー読書会
Toshifumi863 views
マルチコアを用いた画像処理マルチコアを用いた画像処理
マルチコアを用いた画像処理
Norishige Fukushima51.6K views
線形微分方程式線形微分方程式
線形微分方程式
HanpenRobot1.1K views

Recently uploaded(7)

lt.pptxlt.pptx
lt.pptx
tomochamarika39 views
SSH超入門SSH超入門
SSH超入門
Toru Miyahara12 views
図解で理解するvetKD図解で理解するvetKD
図解で理解するvetKD
ryoo toku84 views
robotics42.pptxrobotics42.pptx
robotics42.pptx
Natsutani Minoru165 views

虫食算を作るアルゴリズム 公表Ver