AHC065参加記
はじめに
AtCoder Heuristic Contest 065 に参加し、304位(perf 1471)でした。
今回は初めて本格的にAIを使ってコーディングするスタイルでやったので、そのあたりも含めて参加記を書きたいと思います。
問題
- 縦20x横20のグリッドに番号のついた箱が敷き詰められている
- グリッドにベルトコンベアを設置して番号順に箱を搬出する(搬出口はグリッドの上部中央のマス)
- ベルトコンベアの条件
- サイクル状でなくてはならない
- ただし2マスのみからなるベルトコンベアは許容(実質的に隣あう箱をスワップすることになる)
- 同じマスに置けるベルトコンベアのレールは2つまで
- 異なるベルトコンベアを同時に動かすことはできない
- なるべく少ないターン数(ベルトコンベアを一マスだけ進めるのを1ターンと数える)ですべての箱を搬出せよ
解法
縦2x横Nの横長ベルトコンベアと、縦Nx横2の縦長ベルトコンベアを敷き詰め、次の箱を搬出するまでを1遷移としたビームサーチを行いました。
ベルトコンベア
縦2x横Nの横長ベルトコンベアと、縦Nx横2の縦長ベルトコンベアを敷き詰めることでどの位置にある箱であっても上下左右自由に動かすことができるようになります。
これにより次の箱を搬出口まで最短距離で運ぶことができるようになります。
ビームサーチ
次の箱を搬出口まで最短距離で運ぶにしても複数のルートがあるため、ビームサーチで探索してよいルートを選ぶようにしました。
次の箱を搬出するまでを1遷移としています。ルートの選び方は全パターンを試すことはできないため、方向転換を2回まで(例:左右に動いてから上に曲がり、再度左右に曲がるなど)とするルートに絞りました。
評価関数はターン数 + 1~8個先の箱と搬出口までの距離としています。
正確にいうと、T(i) : 箱0~箱iを搬出するまでにかかった通算ターン数、D(i) : 箱iと搬出口のマンハッタン距離とした場合、評価関数 E(i) は
E(i) = T(i) + Σ (D(i+j) / j) [j = 1〜8]
としています。
意味合い的にはこの後近々搬出することになる箱が搬出口に近いほうがうれしいのでそれを考慮しています。jの数が大きくなると減衰するのは、実際にその箱が次の搬出対象になるまでに位置が変わってしまっている可能性が高くなるのを考慮しているためです。
このほか番号が隣り合う箱同士の距離なども少し検討しましたが、大きな効果が出なかったので採用はしませんでした。
反省点
1個ずつ搬出するやり方にとらわれ過ぎた感じはします。感想戦を眺めた感じだと、まとめて一気に搬出できるような方法が強かったようですので、そこにあまり思い至らなかったのは少し頭が固かったかなというのが反省点です。
連続する箱同士を近づけてまとめて運び出せないかというのは少しだけ頭をよぎったのですが、評価関数で箱同士の距離を考慮する程度しか具体案が思い浮かばず、試した結果もいまいちだったので、そこで案自体をボツにしてしまいました。
ビームサーチで遷移の選択肢が限られていたことと、盤面の重複除去が考えられていなかったことで、導入してもあまり効果出せなかったのかなという気がしています。
あとビームサーチでもまだ伸ばす余地がありそうなので、そのあたりも力不足を感じました。
AIの使い方について
今回はコーディングにAIを活用しました。使ったのはGemini (高速モード)です。無料で使える範囲です。また、ブラウザのチャット欄を使っています。
基本的には方針は自分で考え、その方針でAIにコードを書いてもらうという使い方をしました。
開始~30分
最初は横長(高さ2x幅N)、縦長(高さNx幅2)のベルトコンベアをそれぞれ敷き詰めて、一つずつ上→左右で順番に箱を出すシンプルな方針とし、それを実現するコードを書いてもらう
~1時間30分
最初のコードをベースに経路を複数通り試すビームサーチに変更したコードを書いてもらう
~3時間
ビームの幅・深さを調整したり、評価関数を改善したり。一部コードは書いてもらいましたが、コードは壁打ちした結果を参考にして自分で修正するのがメイン。
~4時間(コンテスト終了)
KotlinのコードをC++に変換してもらう。その結果を使ってビームの幅・深さを調整。
これで順位が50位くらい浮上した気がするので思った以上に効果がありました。
途中、動かないコードやWAになるようなコードを書くこともありましたが、その場合は実際の出力結果を渡したり、以下のような感じでビジュアライザの結果でおかしいところを教えると比較的スムーズにデバッグできた感じでした。
感想
結果自体はいまひとつでしたが、今回一番の課題だったAIを使いながらのコーディング自体は結構スムーズに進められましたし、ビームサーチのアプローチ自体はそれなりに上手く進められたと思います。自分が課題と思っていた点に対して取り組めたということで、いい経験が得られたという点は満足です。ビームサーチの評価関数を工夫して結果が少しずつよくなるというのは、ヒューリスティックではオーソドックスなことだと思いますが、自分ではあまり経験してこなかったので、その点も満足です。
ここまで読んでくださりありがとうございました。