2014-05-04

[][] TCO14 Marathon Round1 21:23 はてなブックマーク -  TCO14 Marathon Round1 - TopCoderの学習のお時間

http://community.topcoder.com/longcontest/?module=ViewProblemStatement&rd=15938&pm=13132

問題


yowaさんのスライドを参照。

http://topcoder.g.hatena.ne.jp/yowa/20140424

やったこと


問題読む→はい、いつものビームサーチのパターンですね

2次元グリッド上でなんかゲームやって、1手ごとならビームサーチ、全体を構成するのなら焼きなまし、というパターン最近多すぎて飽きてきた…

ターン数が10000と多くて、評価関数で色々やろうとするとビーム幅小さくなってどうやってもスコア下がってしまうので、評価関数はごく簡単にしてひたすら高速化を頑張った

探索空間


C=4の場合は1手で消せるところ、C=5,6の場合は1手か2手で消せるところを全探索

始めは高速化のため、前回動かしたところの周辺だけ探す、ということをやっていたけれど意味なかった

ビーム幅は、時間をいっぱいまで使えるよう実行中に残り時間を見ながら動的に変える

評価関数の要素


  • 累計の得点
    • 連鎖を全部シミュレートしてしまうのはあまり意味がなく、得点が0か1か2以上か、だけ判定した
  • 2×2のブロック中に3つ同色がそろった箇所・2つ同色がそろった箇所が、盤面内に何個あるか

データ構造と探索方法


struct Board{
    uint64_t f[20];   // 各セルがどの色か。最高6色、番兵として使う無効分も入れて7色なので1セル3bitで収まる。周囲2マスずつ番兵にするので20*20分確保
    uint64_t v[15];   // 各2×2の領域がどのような状態か。15×15個分確保。
                      // 3つ同色のパターン:4個、2つ同色*2のパターン:3個、2つ同色*1のパターン:6個、同色無しのパターン:1個 で合計14個なので1つ4bit
    uint64_t v2[15];  // 高速化用。基本的にはvと同じだけど、一度探索してみた結果1手や2手では消せないとわかった箇所は、
                      // 0(無効を意味する)で上書きして再度調べないようにする
};

探索するときは、たとえばv2が「3箇所そろっていて右下だけ違う色」を示しているときは、次のような状態になっている。

 AA
 AB

下の図のXの箇所を調べ、そこの色がAだった場合、それをBの箇所に持ってくる動きを候補として採用する。

 AA_
 ABX
 _X_

C=5,6でXの箇所が候補にならなかった場合は、次に、2手で揃えられる箇所として、下の図のYの位置も調べる。

 __Y__
 _AAY_
 YABXY
 _YXY_
 __Y__

v2が「2箇所そろっている」の場合も、同じように2手で揃えられるパターンを全列挙してそこに揃えたい色が入っているかを調べる。

反省


  • 同一盤面の除去をやらなかった
  • 評価関数のパラメタ調整をやらなかった

同一盤面の除去を軽く入れてみたら2%くらい上がったので、もっとこの辺をちゃんとやっていたら通過ラインくらいまで行けていた可能性もある。

詰めが甘いです

結果

  • provisional score : 950346.80(各ケースで1位を100万点とした相対スコアの平均)
  • provisional rank : 10 / 333
  • final score : 952155.96
  • final rank : 10 / 333
  • レーティング : 2334->2371 highest更新