【AHC022】 AHC初参加記 〜入茶しました
みなさんこんにちは。LiKafです。
今回は、2023年8月11日から2023年8月20日まで行われた、RECRUIT 日本橋ハーフマラソン 2023夏(AtCoder Heuristic Contest 022)に参加してみたので、参加記録と、(私なりの)簡単な解説を書こうと思います。
参加しようと思った理由
特に大きな理由はありません。
強いていうなら、リクルートさんがスポンサーであるというのと、夏休みで何か刺激が欲しかったからです。
そもそも、いままでAtCoderをやってきて、アルゴリズムの方はほぼ毎週出ていたのですが、AHCのことは正直一度もやってみようと思いませんでした。
一番大きな理由としては、ABCは『答えを出す』ということを目的にしてるが、AHCは『精度を競う』という、明確な違いがあると考えていたからです。
これまでABCで学んできたことが役に立たないのもあまり嬉しくはなかったし、ABCは好きだけど、その†違い†のせいでAHCが面白いかどうかわからないから、あえてそれに取り組まなくてもいいかなと思っていました。
参加記録
ダラダラ書いても仕方ないので、早速どのようにAHCに取り組んだのかを書いていきます。
(私の最終的な解法の解説はこの次の『簡単な解説』にあるので、解説だけ見たい人はスキップしてください)
結果的には、私の初参加のAHCであったAHC022は、
こんな感じでした。
実際の提出者は1000人ちょっとだったので、3382人中241位というわけではないのですが、まあ初めてにしては頑張った方だと思います。(そうだよね?そうだと信じてる)
8月11日(初日)
軽く問題文を読んでみました。
正直一回読むだけでは何もわからず、まぁまだ10日もあるからいいやと思って、とりあえずサンプルコードを提出するだけして、放置しました。
Web版ビジュアライザ・入力ジェネレータ?何これ。
8月12日 ~ 8月18日
みてもらうとわかると思うのですが、8/11から8/19日まで、何もしていませんでした。
何をしていたのでしょうか。本当に後悔しかありません。
問題文が予想以上に難解で、実家に帰っていたことも相まってYouTubeを見るだけの生活をしていました。マジで勿体無いです。大反省。
8月19日、20日(ラスト2日)
一緒にAHCをやろうと話していた研究室同期から催促の連絡が来て、流石にやるかと思って再開しました。
問題文を読み直して、意味不明すぎて絶望しました。
諦めずに何度か読み返したり、図に書いたりしてやっと理解できました。
問題としては、以下の感じです。(厳密にはコンテストページを確認してください。雰囲気だけです。)
さあ!問題文も理解し、僕の考えた最強のコード!を提出しました。
11,291。
サンプルスコアよりも300分の1になって大泣きしました。
ダメだ。次こそは。
WA。
もうどうしようもありません。
サンプルコードを忠実に再現し、微調整だけしてとりあえず出してみました。
3,476,702。
サンプル +9,079か、はぁ。むず。
サンプルコードが何をしたいかほとんど読んでなかったので、一度読み直すことにしました。
なるほど、
のか。うん、もうそれでいいじゃん。
でも、スコアの出し方的に、測定コストは最小限で済んでるけど、配置コストがまずそう。
最大Nは100だから、温度としては1000度になる場所があって、その周りは0度になる可能性がある。
その周囲だけで、4*10^6のコストがかかってしまうということで、
今0度にしてる出口セル以外の場所を、出口セルの最高温度と最低温度の真ん中の値にすればいいと思いつきました。
そうすることで、最高温度が1000度の時でも、周りの温度は500度だから、その周囲だけで、10^6で済みます。(その分0度の時もコスト10^6かかるけど、それ加味してもコストが半分に抑えられる)
出してみよ
13,435,512❗️
スコアが4倍になった!!あ!!AHC楽しい!!!
セルを見分けるための温度差をサンプルのまま10度にしてたけど、これが最適かはわからないから、これを色々いじったり色々してみたりして、これまた楽しい!
配置コスト下げるのが正義だということで、温度差を少しでも下げる方法を考えました。
今は出口セルと、それ以外の場所の温度が急に変わってるけど、ここをもっと滑らかにすればよさそう。
やってみました
131,275,372❗️
ああああ!!!!桁が!増えた!!!AHC楽しい!!!
AHCをまともに始めてから4時間が経ちました。
もうこれ以上改善案が思い浮かばなくなったので、今まで放置してたWeb版ビジュアライザ・入力ジェネレータ・ローカルテスタを使ってみることにしました。
ローカルテスタはサンプルの100個をいちいち実行して比較していたらやってられれなかったので、まとめて実行して結果を出すシェルスクリプトを書いたりしました。
ビジュアライザは神です。
頭の中でしか考えていなかったものを、視覚的に考えれるのはとても重要でした。
提供されているツールは全部使ったほうがいいです。確実に。
ビジュアライザを見ると、(本来測定の様子を動画で見れます)
142度に設定しているところを642度と測ったりしていました。
標準偏差Sは実は0~900まで取りうるので、数度の差なんて一瞬で計測誤差として消え去り無意味な情報になります。そりゃうまくいかないわけです。
はてどうしたものか、
Sが大きくて、誤差がえぐいぐらい生じても、この温度ならこの座標だ!と明確にわかるような温度設定にしないといけません。
そこで、一点だけ1000度にして、そこを探すことで、その一点から出口の相対的な位置」を特定し、どの出口セルかを推測できる
と考えました。
具体的には以下の手順です。Sがある程度大きい時、
各出口セルと基準の一点(0, 0)の相対位置vi(iは1~N)を全て求めます。
基準の一点(0, 0)を1000度にし、他を0度にします。
ある入り口セルからAnotherSpaceに侵入し、そこから、可能性のある相対位置viだけ逆方向に移動し、そこで二回計測します。
その平均が最も高い i が答えと判断します。
viを消します。
これをすることで、多少大きな誤差があっても、設定した温度に差があるのと、二回計測できて均すことができ、正答率が高くなります。
ただしこれだと、O(N^2)回計測(+移動つき)しているので、計測コストがかなり大きくなります。でも、スコアの計測方法として、0.8に対して、不正解の答えの数だけ累乗されるのは洒落にならないので、正確さを優先しました。
だしちゃお
237,214,343❗️
最高だあああ!!!!!!だのしいいい!!!
でもこの工夫をしても、Sが500を超えてくると誤差によってうまくいきませんでした。(スコアが1になってしまう)
必死で誤差が大きい時の方法を考えたのですが、思いつかなかったので、
スコアの計測方法
⌈(10^14)*(0.8^W)/(配置時コスト+計測時コスト+10^5)⌉
から考えて、配置コストと計測コストを0にしました。
そうすることで、W=75だとしても、50程度スコアを稼げます。
当然計測コストは0、つまり計測はしていないので、ランダムに予測します
追加でハイパラメータを変えたり微修正を繰り返して、
391,525,797❗️❗️❗️
ヨシ!AHC楽しい!!!!!!!
以上になります。
簡単な解説
最終的な提出コードは以下です。
思いつくままに書いたゴミカス適当コードなので、読まないでください😉
上にも書いたのですが、もっと端的にいうと、
標準偏差が小さい時(Sが3以下)
誤差が少ないのでサンプルコードを参考にして、
各出口セルに対して温度を2度ずつ変える+温度を均す
数回温度を測定し、それっぽい平均が出た時点で場所を特定する。
標準偏差がある程度の時(Sが4以上700未満)
誤差が大きいことが予測されるので、一箇所だけ高温にして、その場所を探すように測定を行うことで、自分の場所を特定する。
標準偏差が大きい時(Sが700以上)
もはや計測しても意味を持たないので、設置コストと計測コストを0にしてランダムに予測し、50程度のスコアをもぎ取る。
結果
やったあ!!入茶だ!楽しかった!
感想
えげつないほど楽しかったです。
最初の1週間何もしてなかったのが本当に悔やまれます。
あと、今回AHCに初めて出てみて一番強く思ったのは、冒頭に書いた
これは、半分ほんとで半分嘘です。
問題を考えるという点で根本は一緒だし、温度を滑らかに配置する時にも私はBFSを使ったし、オーダーの考え方も使うし、解法によっては二分探索を使う人もいました。
他にもアルゴリズムや、アルゴリズム的な思考は沢山活かせると思います。
あと、コンテスト後に他の人の解説を見るのも楽しいです。
ABCと違って、本当に答えがないので、こういう考えでうまくいくんだと理解したり、面白い解法が転がってたりしてすごく良かったです。
次参加するときは、もっと統計の知識をフルで活用してやってみたいと思います。ハイパーパラメータとかも自動で調整できると思うので。
たった二日間でしたが、コンビニに行く時も何してる時もずっと頭の中がAnotherSpaceのことでいっぱいで困るレベルでハマりました。
ここまで熱中したのは久しぶりです。おかげでABCで大敗してしまいました。AHC許しません。
以上が私のAHC022の初参加記録です。
長々とありがとうございました!!
また来月なんか書くので読んでください!!