Chokudai Contest 004: A - マス目に数を書き込む問題
問題
$n \times n$ のマス目に $1 \sim 9$ の数を書き込む。 横か縦一列に見て和が $B_1, B_2, B_3$ のいずれかな区間があれば $B_i$ 点貰える。 点数を最大化せよ。
解法
ふつうに焼きなまし。 適当 1 点更新が強く、近傍の改善もしたけどはあまり有効でなかった。 スコア差分の計算はしゃくとりぽくやる。 試行回数は $2 \times 10^6$ ぐらい。
他の人の解法を見るに、ひたすら高速化するだけの勝負だったぽい。 「$1$ 回の試行」の定義にもよるがとりあえず $10^7$ 回に乗せる必要はありそう。 $8$ 時間や $1$ 週間あれば天才が生えてくる可能性はあるが $2$ 時間だと初手愚直をひたすら定数倍が最適ムーブとなる。
リンク
- 問題ページ: https://atcoder.jp/contests/chokudai004/tasks/chokudai004_a
- 自分の提出: https://atcoder.jp/contests/chokudai004/submissions/7232262
- agw さん Togetter: https://togetter.com/li/1397914
他の人の解法
ats5515 さん: 1652578 点 1 位
普通に焼きなましました。近傍は一点更新、長さが10より大きい区間は無視して影響ある区間すべてを愚直に計算した。
— ATS (@ats5515) August 31, 2019
焼きなましの温度は30から10に線形に減らした。
— ATS (@ats5515) August 31, 2019
主に近傍選択を試すのに時間を費やしたけど一番単純な方法(1点を別の数に変える)が一番良かった。
正直どのへんで差がついているのかわからないけど温度管理なのかな
提出コードを借りてきて見てみると $2 \times 10^7$ 回試行があるので、彼の勝因は高速化ぽい?
math さん: 1631928 点 2 位
1マス選んで値をランダムに変える焼きなまし。試行回数は1.5 * 1e7 で 1631928。試行回数を10倍すれば1650000は間違いなく超えられるが…
— まーす (@__math) August 31, 2019
main - Ans::calcDiffの10.74%のうちの大半がSAの計算なので、ここを高速化するだけでも試行回数は5%くらい増やせて、この程度のスコア差だとこれでも効いてくる pic.twitter.com/p2P8zEpGvX
— まーす (@__math) August 31, 2019
tanzaku さん: 1625536 点 3 位
gasin さん: 1609480 点 4 位
1点をランダムな値に書き換えるシンプルな焼きなましをしていた
— гасин (@_gacin) August 31, 2019
試行回数は $5 \times 10^6$ らしい
sumoooru さん: 1605376 点 5 位
Chokudai Contest 004 お疲れ様でした。多分5位
— sumoru (@sumoooru) August 31, 2019
やったこと
ある場所の数字を変えて、たまにその隣の数字も先の増分だけ減らすような焼きなまし。試行回数2.5M回くらい
スコアの差分は縦横の尺取り法
TL見て焼きなましの温度を30 -> 0 から 30 -> 10にしたら1万点くらい良くなった #chokudai_004
— sumoru (@sumoooru) August 31, 2019
同じことやってる。温度調節での 1 万点は誤差な気がするが
koyumeishi さん: 1591239 点 6 位
雑にビームサーチしただけ。 評価関数工夫してる暇なかった (多分焼いた方がいい気がする)
— koyumeishi (@koyumeishi_) August 31, 2019
ビームサーチ、
— koyumeishi (@koyumeishi_) August 31, 2019
* 普通に左上から
* 左上から互い違い(ヘビ)
* 左上からのマンハッタン距離順
の3種類走査順試したけど、ヘビが一番強かったっぽい (評価関数的にそれはそう)
ビーム幅は 4000-6000 ぐらいでした (結構時間に余裕はあって 8000 ぐらいにもできたんだけど、いつもの良い状態が蹴りだされるアレでスコアが下がりそうなのでほげ (提出制限もあったので試してない))
— koyumeishi (@koyumeishi_) August 31, 2019
ビームサーチを 6 位に乗せれるのガチプロって感じがする。すごい
hos_lyric さん: 1587092 点 7 位
betrue12 さん: 1586162 点 8 位
1点更新の焼きなましで、累積和を使うと1回あたり再計算O(N^2)なんだけど、更新前も更新後もB3を超えるようになったらそれより長い区間は無視してよくて、それをやると反復回数をかなり稼げた
— アルメリア (@armeria_betrue) August 31, 2019
tomerun さん: 1581564 点 9 位
ランダムな点を別の数に変えるSA。変化させた点の周囲だけ評価。縦方向の評価でキャッシュ当たりやすいように90度回転させた盤面も持つ。変化先の値にB3-B2やB2-B1が出やすいようにする(効果があるかは不明) #chokudai_004
— tomerun (@tomerun) August 31, 2019
キャッシュのために $90$ 度回転かしこいけど、 $30 \times 30$ なので $900$ byte だし気にする必要なさそうに見える?
これ見て「そういえば盤面を int
で持ってたけど char
にしたら速くなるかな」と思ってやってみたけどほぼ変わらなかった。
zaki_ さん: 1573465 点 10 位
EvbCFfp1XB さん: 1557634 点 16 位
Chokudai Contest 004 はランダムに数字を変えるSAです。 pic.twitter.com/DX7FQ26Btj
— EvbCFfp1XB (@EvbCFfp1XB) August 31, 2019
$2$ 時間コンでビジュアライザ書いて本体も間に合わせるのえらい
snuke さん: 1512698 点 28 位
適当にやきなました。(マスを変える、隣接を+1,-1する、2*2を+1,-1,-1,+1)
— ꑄ꒖ꐇꌅꏂ🐈 (@snuke_) August 31, 2019
これ以上どうやって伸ばすのか分からず、画像作って眺めてた(何も分からず)#chokudai004 pic.twitter.com/nS6brEjF2S
ビジュアライズで時間溶かしてたでしょ感ある