AHC044の反省
はじめに
今年からHeuristicのコンテストが多くて嬉しいが、AtCoder Heuristic Contest 044は、手も足も出なかったので、ほぼ反省の振り返りになる。
問題
問題は掃除当番を順番に決める問題...というか、1回目は右に行くけど、2回目は左に行くという線路のおもちゃを想像した。各線路を通過する回数に目標値があるので、それにできるだけ近づける問題。
方針
よくわからないので、焼きなましで考えてみる。
スコアの計算
最初、スタート地点に2回戻ってきた段階でループに入る...と思ってしまったが、よく考えると他の社員が奇数回目か偶数回目かも一致しないとループにならない。仕方ないので、愚直にシミュレーションしてみるが、ターン数である
木を作る
2つに分かれる線路のイメージだったので、二分木を作ってみた。ある程度進むと根に帰るようにすると、根のノードの方が巡回される回数が多いので、根に近い方に目標値が大きい社員を置くと良いと考えた。
そこで、目標値を降順にソートし根から順番に二分木を作ってみた。葉に相当する社員は根の社員に戻るようにしたが、これだとみんな同じ回数だけ掃除することになるので、ある高さ以上の社員の
ただ、この方式だと最初の解のスコアも低い上に、焼きなましで回してもまったく更新されない。これで結構時間を取られてしまったが、再度考え直すことにした。
単純にならべてみる
木だと複雑すぎるので、社員を目標値順に1直線上にならべてみた。この時、奇数回目での次の掃除当番を根の社員にすると、根の社員からその社員までを2回通過してから、その後ろの社員に掃除当番が移る当番表が作れる。つまり、目標値が根の社員の
振り返る
最後に提出したもので、公開されている100のテストケースを解いたスコアは74,755,066点。ここから他の人の実装などを見て考え直してみた。
隣接解のバリエーション
近接解を以下の4パターンで作成することにした。
任意の社員
- 社員
の次の掃除当番をi にする(奇数回目/偶数回目)j - 社員
の次の掃除当番と、ノードi の次の掃除当番を入れ替える(奇数回目/偶数回目)j
これでスコアが 95,004,870点(+20,249,804)。大きく変わった
重みをつける
シミュレーションの回数変更
シミュレーション回数を
スコア算出方法の変更
スコアをシミュレーションではなく、トポロジから導出する方法を使っている人が多かった。目標値
試してみる
とりあえず一番スコアが高かった重みつけまでやったパターンを提出してみると、200番台ぐらいのスコアがでた。ここまでなら時間内にだせたのでは?と思うのとともに、もっと上位の狙うにはどうすれば良いかはしっかり考える必要がある。
Discussion