📝

AHC040参加記

2024/12/09に公開

初めに

2024/11/29(金) ~ 2024/12/9(月)に開催されていた、長期プログラミングコンテストHACK TO THE FUTURE 2025 (AtCoder Heuristic Contest 040)に参加しました。

ルールベース初期解 + 山登りというかなり単純な手法で、本番275位を取ることができました。以下、思考過程の記録を残します。

今回良かったこと

  • ルールベースの初期解は、AHCラジオで紹介されていた方法で作れていた
  • 「山登り法」というものを明示的に理解して使えた

ルールベース初期解

入力生成の項目を見ると、段ボールの実際の辺の長さは、必ず[10^4, 10^5]の範囲です。
A = 5×10^4 × sqrt(N) × 1.2 ~ 1.3 として、A×Aの正方形を作ることができれば、大まかに充填率80%程度にできそうな気がします。

長方形を全て縦長にしたうえで横に積んでいき、幅がAである「Aブロック」を作ってみます。


工夫点としては、各「Aブロック」ごとにクエリを出して実際の大きさを測定し、予想より大幅に小さい/大きい場合には段ボールの数を増減して調整する処理を加えました。

これを縦に積みます。 ⇒ 『状態1』

最終列を横倒しにすると、場合によってはスコアが改善します。 ⇒ 『状態2』

また、最終列を削って、横から付け直すと、場合によってはスコアが改善します。 ⇒ 『状態3』

この『状態1』『状態2』『状態3』のうち、一番スコアが高いものを、ルールベース初期解としました。

山登る

Aブロックの計測がsqrt(N)回、そのあとの結果出力が3回なので、N = 30の場合でもsqrt(N) + 3 = 9 <= 15 = N/2となり、確実にターン数が余ります。

なので、残りはとにかくランダムに回転させてみて、スコアの向上を狙いました。 「ランダムに回転した結果スコアが向上したら、それを新しい拠点にして、また回転させていく」 という山登り法を実装したところ、順位が50~100位ほど上がったようでした。

参考資料

「山登り法が何か知らない」 ⇒ terry_u16さんのスライドがとても分かりやすかったです。
https://speakerdeck.com/terryu16/metahiyurisuteikusudeguang-garu-jie-keta-noshi-jie

「山登り法の実装が分からない」 ⇒ kaede2020さんのYouTubeがとても分かりやすかったです。
https://www.youtube.com/watch?v=YecMUN7_OL8

最終結果

私用が重なったこともありこれ以上の改善はできませんでしたが、最終結果は275位で、ギリギリ初の青パフォーマンスを取ることができました。

ソースコードはこちら。
https://atcoder.jp/contests/ahc040/submissions/60450935

終わりに

AHCラジオでも紹介されていた筋の良いルールベース初期解を思いつけたことと、「山登り法」という名前を明示的に理解できたこともあり、個人的にはある程度満足のいく結果でした。

一方で、まだまだ行けるのでは?という気もしており、AHCラジオで話があった『階段状に積んでいき、残り面積を評価関数にしてビームサーチする』という方法や、『カルマンフィルタによって真値を推定する』という方法など、延長戦でいくつか試してみたいと思います。

そもそも『ビームサーチ』や『カルマンフィルタ』を明示的に理解するところから始めないと。。。まだまだ先は長そうですが、一歩一歩学んでいきます。

Discussion