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.

Code iq interpretation_summary_publish

2,749 views

Published on

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Code iq interpretation_summary_publish

  1. 1. 株式会社フィックスターズ 「最適解を目指せ!!」 (ナンプレ盤面問題) 解説会 出題意図と典型解法について 田中伸明
  2. 2. 問題おさらい ※なんで1/6 ? →最初1/9にしてみたら、あまりにもスカスカだったの でちょうど良さそうなくらいに調整しました ● 500*500の数字の盤面 ● 1/6はすでに数字が決 まっている ● 残りの5/6に好きな数字 を入れて、盤面をできる だけナンプレっぽくする
  3. 3. 問題を作るときに考えたこと ● 好きな言語や好きな環境で挑戦できる ● ルールが既存のゲーム・パズル等を元にしており理解 しやすい ● とりあえず0点ではないスコアなら簡単に取れる ● アルゴリズムを工夫して計算量なんとかしたい程度に はデータ量が多い ● 少し工夫すれば並列化も可能 参加の敷居は下げつつ、頑張りたい人にはその余地も残 す、という問題を目指しました
  4. 4. 結果 ● 参加者数46名 ● 7割程度がC/C++。ついでRuby・Pythonが数名ずつ ● 平均提出回数2.3回 1位 234602点 machyさん 2位 224804点 Mi_Sawaさん 3位 223816点 footaさん 20万点以上    16名 15万点〜20万点 13名 10万点〜15万点 13名 5万点〜10万点  4名
  5. 5. 想定していた典型解法 1.それなりに良い初期値を選ぶ 2.逐次的に改善していく 3.たくさん繰り返す この手の「よりよい解を見つけろ」というタイプの問題 では、非常に良くあるパターン
  6. 6. 想定していた典型解法 1.それなりに良い初期値を選ぶ 2.逐次的に改善していく 3.たくさん繰り返す
  7. 7. 初期値の選び方 ● DPなどでひとまず横向きだけを最適化する →縦向きや3*3ブロックの分を改善するのが難しい ● 周囲の数字と重複しないものを選ぶ benchmark2みたいなヤツ →なんとなく重複しないだけではスコアは出ない ● 9*9のナンプレ盤面の繰り返しパターンで埋める →意外と強かった
  8. 8. ナンプレ盤面で埋める 例えば右のようなナンプレの盤 面を用意し、数字が未決定の箇 所に繰り返し敷き詰める。 これだけで15万点くらい出る 1 2 3 4 5 6 7 8 9 4 5 6 7 8 9 1 2 3 7 8 9 1 2 3 4 5 6 2 3 1 5 6 4 8 9 7 2 3 15 6 4 8 9 7 2 3 18 9 7 5 6 4 6 4 53 1 2 9 7 8 3 1 26 4 5 9 7 8 3 1 29 7 8 6 4 5 まず、初めから入っている数字を無視して、この盤面 で全体を埋めると、63万点くらいになる 初めから入っている数字の制約によって、これからど のくらいスコアが減るかを計算してみると… 理由:
  9. 9. ナンプレ盤面で埋める期待値 “盤面から9マスを取り出したとき、その全てが初期 状態で数字が入っていないマスである確率”  = (5/6)9 ≒ 19.3% “盤面から9マスを取り出したとき、そのうち1マスに 初めから数字が入っており、その数字が埋めようとし たナンプレ盤面と一致する確率”  = 9 C1 ×(5/6)8 ×(1/6)×1/9 ≒ 3.9% “同じく2マスに数字が入っていてかつ一致する確率”  = 9 C2 ×(5/6)7 ×(1/6)2 ×(1/9)2 ≒ 0.3% これらを合わせると、  63万点×(19.3%+3.9%+0.3%) ≒ 148000点 このくらいのスコアは取れると期待される
  10. 10. 想定していた典型解法 1.それなりに良い初期値を選ぶ 2.逐次的に改善していく 3.たくさん繰り返す
  11. 11. 逐次的に改善する 「現在の盤面からちょっとだけ変更してみて、スコア が上がるなら採用する、上がらなければ元に戻す」 これを繰り返す。 何も考えていないような方法にも見えるけど、これで かなり改善していく ● スコアが上がる場合だけ採用するのではなく、下が る場合にも確率的に採用する手法(焼きなまし法) もあり、一般的にそっちのほうが強い。 ただしどのくらいの確率で採用するかのパラメータ 調整が必要
  12. 12. 盤面をちょっとだけ変更 一番単純なのが 「1マスを選んでランダムな他の数字に変えてみる」 様々な方法が考えられ、各自の工夫が見られました。 ● 複数のマスを同時に変更する ● 盤面全体からではなく、いったん小さいブロックに 区切ってその中だけで選ぶ ● 1〜9すべて試し、一番良いものを採用する 28 9 7 63 1 2 6 4 5 9 39 7 8 28 9 7 63 1 9 6 4 5 9 39 7 8
  13. 13. 想定していた典型解法 1.それなりに良い初期値を選ぶ 2.逐次的に改善していく 3.たくさん繰り返す
  14. 14. たくさん繰り返す ■ハイスコアを狙おうと思ったら速度は重要です 1マス変えたときにスコアを再計算するのは、方法次 第で数十倍の速度の差が出る ここまで違うと、いくら長めに計算を回しても埋め られない差になる ■比較的簡単に並列化可能です 例えば盤面の上の方を処理している間は、下の方は 無関係なので並列に処理できる あまりやっている人はいなかった? 便利なライブラリ等色々あるので試してみましょう

×