17
TopCoder Marathon Match 92 Lighting 参加メモ @yowa

TopCoder Marathon Match 92: Lighting (yowa)

  • Upload
    yowaken

  • View
    316

  • Download
    3

Embed Size (px)

Citation preview

Page 1: TopCoder Marathon Match 92: Lighting (yowa)

TopCoder Marathon Match 92Lighting

参加メモ

@yowa

Page 2: TopCoder Marathon Match 92: Lighting (yowa)

どんな問題?

● 壁のある部屋にライトを置いて、できるだけ部屋全体を照らしたい

– 部屋サイズS: 10~50

– ライトの数L: 2~10

– ライト半径D: 2~10

– 壁である確率p: 0.1~0.3

● スコア: 照らしてる割合

Page 3: TopCoder Marathon Match 92: Lighting (yowa)

やったこと

● 大ざっぱなライトの配置を決める– ライト位置を各セルの中心・角・辺中央に限定

– 照らす範囲もすごい雑に計算

– Greedy に配置した後、焼きなまし● 焼きなましの近傍: ライトを1つ任意の位置に移動する

● 位置を微調整する– 照らす範囲の計算をもうちょい細かく

– 焼きなまし● 近傍: ライトを現位置から±1セル分以内で動かす

Page 4: TopCoder Marathon Match 92: Lighting (yowa)

今回の問題のキモ(?)

● スコア計算をどう実装するか?

– 複数ライトが照らしている面積の和(union)を求める

Page 5: TopCoder Marathon Match 92: Lighting (yowa)

スコア計算の詳細(定義)

● 各セルをf^2個のサブセルに分割(分割数 f=100)● サブセルの中央にライトの光が届いていれば、そ

のサブセル全体が照らされているとみなす

● 光が届く⇔ライトとの距離がD以内、かつ

       ライトへの線分が、壁と交わらない

       (壁に接するのもアウト)

Page 6: TopCoder Marathon Match 92: Lighting (yowa)

スコア計算の(公式テスタの)実装

● すべてのサブセル(= f^2・S^2)について

● すべてのライト(= L)からの線分が

● すべての壁(= p・S^2) と交差しないか確かめる

● → f^2・p・L・S^4 回の交差判定

Page 7: TopCoder Marathon Match 92: Lighting (yowa)

スコア計算の(公式テスタの)実装

● すべてのサブセル(= f^2・S^2)について

● すべてのライト(= L)からの線分が

● すべての壁(= p・S^2) と交差しないか確かめる

● → f^2・p・L・S^4 回の交差判定

重い

Page 8: TopCoder Marathon Match 92: Lighting (yowa)

スコア計算の実装

● 公式テスタ→ひどいケースは1回で十数秒かかる

● 焼きなましなどをやりたい

→ スコア計算は何万回と行う必要がある

● 効率化・簡略化による高速化が不可避

Page 9: TopCoder Marathon Match 92: Lighting (yowa)

スコア計算でやったこと

● 部屋を(サブセルではなく)縦に細くスライスする

Page 10: TopCoder Marathon Match 92: Lighting (yowa)

スコア計算でやったこと

● 部屋を(サブセルではなく)縦に細くスライスする● 一つのライトが照らす範囲 ≒

– 各スライスについて

– 各壁がつくる影の区間を[y_min, y_max]で求め

– すべての壁について union をとって、

– 反転(陰→陽)したもの

Page 11: TopCoder Marathon Match 92: Lighting (yowa)

スコア計算でやったこと

● 部屋を(サブセルではなく)縦に細くスライスする● 一つのライトが照らす範囲 ≒

– 各スライスについて

– 各壁がつくる影の区間を[y_min, y_max]で求め

– すべての壁について union をとって、

– 反転(陰→陽)したもの

● 複数のライトが照らす範囲 ≒

– スライスごとに、各ライトが照らす範囲を union

Page 12: TopCoder Marathon Match 92: Lighting (yowa)

計算量?

● サブセルの縦方向の分割が減ったけど

– 区間の union が O(1) じゃないぶん増えた

– ここは相殺する感じ

● おおまかに、元の計算量の f^2 が、

スライス分割数 f になる、くらいの改善?

Page 13: TopCoder Marathon Match 92: Lighting (yowa)

計算量 ?

● 前ページの計算量– ライトが照らす範囲を毎回計算する前提

● 一度計算したライト位置についてはメモしておく● 全部メモ済ならば、

– すべてのライト(= L)について

– すべてのスライス(= f・S)における

– 照らす範囲(高々S+2個の区間)を union する

● ので、2f・L・S^2 とかかなあ?

Page 14: TopCoder Marathon Match 92: Lighting (yowa)

精度を犠牲に高速化

● セルごとの分割数 f = 100 を減らす

● 最初のGreedy&焼きなましでは f = 2 で● 次の微調整ターンでは f = 10 で

Page 15: TopCoder Marathon Match 92: Lighting (yowa)

やらなかったこと

● 厳密なスコアの計算

– f = 100 じゃないと正確じゃないけど仕方ないね

– いまになって出力を眺めたら、円の角が欠けてる例が散見されて悲しみを覚えた

こっちに置けるのに…

Page 16: TopCoder Marathon Match 92: Lighting (yowa)

やらなかったこと

● 厳密なスコアの計算

– f = 100 じゃないと正確じゃないけど仕方ないね

– いまになって出力を眺めたら、円の角が欠けてる例が散見されて悲しみを覚えた

● 小さいケースで厳密解

– Dが小、 L が少など:円が互いに交わらない解が存在

– Dが小 → 範囲内の壁状況のパターンも限定的

– 全パターンの網羅が可能のはず

Page 17: TopCoder Marathon Match 92: Lighting (yowa)

まとめ

Splatoon っぽい……Splatoon っぽくない?