tipstar0125 / ahc

ahc
0 stars 0 forks source link

yukicoder score 6 #1

Open tipstar0125 opened 1 year ago

tipstar0125 commented 1 year ago

問題:https://yukicoder.me/problems/no/5017 解説:https://yukicoder.me/problems/no/5017/editorial

ぷらちなさんWriter記:https://platinum-prog.hatenablog.com/entry/2023/07/25/181223 rhooさん解法(ビムサ):https://twitter.com/rho__o/status/1681665412843421699 pokaさん解法(貪欲):https://twitter.com/poka_cp/status/1680559487369838596

tipstar0125 commented 1 year ago

出現確率分布の活用に関して

tipstar0125 commented 1 year ago

ビームサーチ

tipstar0125 commented 1 year ago

コンテスト中の解法 ・S or L or Rの中で最適な動作を評価関数で判定 ・レベルアップを最優先として、次に残り体力が少なく倒せそうな敵ならスコアを高くした ・死んだときのスコアは-INF ・スコア同じ場合は留まることにした ・周りに敵がいない場合は左右どちらかに確率で移動

得点:2,859,502 サンプル得点:約36,000

tipstar0125 commented 1 year ago

まずは貪欲法をやってみたい。

なるべく多くの敵機を破壊する貪欲法 一番早く破壊できる敵機だけを狙えば良い動きができそう 自機を動かす際、次のターンに敵機に衝突してしまったり、敵機に包囲されて回避不能になってしまわないように注意

tipstar0125 commented 1 year ago

貪欲法

注意点!!!:自機と敵の距離が1になって、敵を消滅できなければ、次のターンで確定Game over

tipstar0125 commented 1 year ago

貪欲法の提出

コンテストでも貪欲書いたけど、Game overのタイミングを勘違いしてた。。。 「自機と敵の距離が1になって、敵を消滅できなければ、次のターンで確定Game over」

check_left/right_enemyの判定dy < tdy <= tに修正:3,810,330点 https://yukicoder.me/submissions/895616

judge_collision_left/rightを改善:3,891,630点 次のターンで目の前に敵がくる場合も衝突判定していたが、実際は倒せれば問題ないので、倒せる場合は衝突しないとした。 https://yukicoder.me/submissions/895624

ランダムで左右に動くと、敵がいないところを反復横跳びして、終盤敵を倒せないので、強制的にどちらかに流れてしまった方が点数取りやすいのかもしれない。

tipstar0125 commented 1 year ago

もう少し貪欲を頑張りたい。 改善点としては、正面・左右どこにも倒せる敵がいなかった場合、どう動くのか最適かを適切に求めたい。

ただし、2手先以上は衝突を回避しつつ、どこで留まるべきかを決めるのは貪欲では厳しそう。 衝突回避は難しいので、 一旦敵がいるところまで探索して、左右どちらが有利か決める方針を書いてみるのはよさそうな気がする。

左右どっちに行った方が良いのか、敵の密度を求めると良さそうな気もするので、それでやってみる。

pokaさんも貪欲だったから、後でみておきたい!

tipstar0125 commented 1 year ago

一旦敵がいるところまで探索して、左右どちらが有利か決める方針を書いてみるのはよさそうな気がする。

3,777,131点 https://yukicoder.me/submissions/895625

隣より先を探索しても、すぐ倒せなければ、あまり意味ないかも(新しい敵が出現したりするので) あと、ビジュ見ると比較的弾幕なので、敵が過疎っている状況(序盤)をがんばっても意味がなさそう。

tipstar0125 commented 1 year ago

今気づいたんだが、levelはpowerで上がっていくけど、scoreはhpであがっていく。。。 scoreとlevel同じだと思ってた。 最初はレベルアップ重視で、後半はスコア重視にすると良さそう。

書いてみた:3,755,820点 https://yukicoder.me/submissions/895760

seed0002でうまくいっていないっぽい。 目の前、左に敵がいなくて、右に倒せる敵がいない場合は留まっている。 敵がいないとき、倒せないときの優先順位とタプルのソートの影響。少し工夫がいる。

評価値計算で、hp or pが小さく、tが大きい場合は0になってしまい、正しく評価できないので1e6をかけて評価したら、ちょっとだけスコア上がった。 3,869,015点 https://yukicoder.me/submissions/896736

tipstar0125 commented 1 year ago

貪欲色々改善したけど、超絶激固弾幕??があるっぽくて、ローカルテストケース100ケで問題なくても、提出したら点数が伸びない。どこかでGame overになっている。 貪欲は3.8-3.9Mで限界説。

試した改善

tipstar0125 commented 1 year ago

pokaさんコメント: LRSの3択ではなく、どの列の敵を狙うかの貪欲を使ってですが一応4.29Mまででましたよ。 評価値は(敵機のinit_hpとpowerの重み付き和) / (敵機を破壊するまでにかかるターン) に加えて各列周辺の敵の密度的なものを使っています

コード(Rust) https://yukicoder.me/submissions/896568

tipstar0125 commented 1 year ago

pokaさんのコメントを受けてどの列を狙うかの貪欲を書いてみた。 ただ、全ての列に最短で到達できるターン数を求めるとTLEするので、最大8ターンで到達できる範囲で計算した。 ※途中移動中に敵を倒すこともあるが、評価値には考慮していない

4,137,041点 https://yukicoder.me/submissions/896738

tipstar0125 commented 1 year ago

pokaさんコード(4.29M点)解読 https://yukicoder.me/submissions/896568

Main

  1. 敵情報を入力
  2. preprocess(敵の位置情報更新、両端キューを使って処理圧縮)
  3. greedy(最もスコアが高い列xを取得)
  4. move(x列に移動、衝突するならS、衝突回避できないならnot success、敵機が衝突しなくても目の前に来たらNG)
  5. postprocess(自機を移動、敵機のダメージ及び撃墜判定)

Enemy

  1. init_hp, hp, power, x, y
  2. evaluation: 序盤(レベルが低い時)は敵のpowerを重視、levelがあがるとinit_hpを重視。level=250になると、init_hpだけで評価

greedy

  1. enemies_score_sum: 各列における敵機のinit_hpの総和+周辺敵機のinit_hpの総和(距離の2乗で割る)
  2. 候補になる(先頭の)敵機取得
  3. 各列についてスコア計算
    • 敵機の評価
    • 敵機を撃墜するまでのターン数計算(移動+攻撃)
  4. 最もスコアの良い列を返す

compute_attack_turn

  1. 移動ターン数計算(compute_approach_turn)
    • player, enemiesをclone
    • 移動したい列に到着する最短ターンを求める(衝突判定の場合はS、回避できない場合はINF)
    • 例えば、右に移動したくて、左に避けるみたいなことはしていない
  2. 撃墜ターン数計算

スコア

理解できていない点

tipstar0125 commented 1 year ago

貪欲をさらにがんばろうとすると結局ビームサーチっぽいことになる(すでにビームサーチっぽいけど)。 ビームサーチをやった方がよさそうなので、ここら辺で貪欲を切り上げる。

貪欲まとめ:

重要:評価関数は最終的には問題のスコアに近づくようにした方がよい。やり方には2通りあって、ある閾値(今回の場合レベル)を境に評価関数を変えるとか、レベルごとに重みを変化させる。2つのやり方を混ぜるのもあり。

最大4,296,090点獲得 https://yukicoder.me/submissions/897111

tipstar0125 commented 1 year ago

ビーム打ってみた。 ビームの深さが5までしかいかないので、5ターンでスコアを獲得できない場合は、全てのスコアが同じになって、その場にとどまってしまい、最後まで残ったとしてもスコアが全く伸びない。 https://yukicoder.me/submissions/897194

改善案

bowwowさんツイート:

敵を1体倒すまでを深さ1としたビームサーチ。深さ4の幅8までしかできなかった。 https://twitter.com/bowwowforeach/status/1680521601559691265

tipstar0125 commented 1 year ago

コピー量を減らす案: