LoginSignup
3
1

【日本語翻訳】Atcoderレーティングの計算

Last updated at Posted at 2023-09-25

この記事はAtcoder公式のAtCoder Rating System ver. 1.00を、ChatGPTを使って翻訳した文です。原文がPDFなので、筆者がマークダウン記法での書式に整えて翻訳しました(これ)。

また、原文には書かれていませんが、最終的なレーティングの計算式も追加しました。
というのも、原文を参考にPythonで計算のシミュレーションをしたのですが、結果が一致しませでした。説明が不十分と感じ、AtCoderのレート計算式の考察を参考にして再度計算してみたところ、無事結果が一致しました。数式の意味や細かい数学的な考察なども、AtCoderのレート計算式にとても詳しく書かれていますので、ぜひ参考に。

以下本文です。

Atcoderレーティングシステム ver. 1.00

レーティングシステムの概要

このレーティングシステムは、Elo RatingのようにLogistic Distribution(またはSigmoid Function)に依存していますが、多くの修正が加えられています。各コンテストで「パフォーマンス」という値が得られます。この値は、コンテストでどれだけ良いパフォーマンスをしたかを表しています。過去のコンテストのパフォーマンスはhttps://atcoder.jp/users/USERNAME/historで確認できます。

大まかに言うと、あなたのレーティングは、パフォーマンスの加重平均(最近のコンテストにはより多くの重みがあります)から、$f(レート対象のコンテストへの参加回数)$を引いたものとして計算されます。ここで、$f(1) = 1200$であり、$f$は徐々に減少してゼロに収束します。これは、$X$のパフォーマンスを維持し続けると、あなたのレーティングは$X - 1200$から始まり、$X$に収束するということを意味します。最初のコンテストで非常に低いレーティングを取っても心配しないでください。より多くのコンテストに参加すると、レーティングは非常に速く上がる可能性が高いです。10回以上のコンテストに参加した後は、あなたのレーティングが実力に近いものであると考えてよいでしょう。

パフォーマンスの計算

内部的には、パフォーマンスには2種類あります:$Perf$と$RPerf$(Rounded Performance)。https://atcoder.jp/user/USERNAME/historyに表示されている数字は実際には$RPerf$です。まず、各参加者について、$APerf$(Average Performance)を計算します。特定のユーザーの$Perf$($RPerf$ではない)の履歴を$Perf_1, \cdots , Perf_k$としましょう。$Perf_1$は最新で、$Perf_k$は最も古いものです。この参加者の$APerf$は、以下のように定義されます。

$$
APerf=\frac{\sum_{i=1}^k Perf_i \times 0.9^i}{\sum_{i=1}^k 0.9^i} \tag{1}
$$

新参者の$APerf$は$Center$に設定されます。AGCでは$Center = 1200$、ARCでは$Center = 1000$、ABCでは$Center = 800$です。

参加者数を$n$とし、$i$位の参加者の$APerf$を$APerf_i$とします。このコンテストで$r$位のユーザーの$Perf$は、以下の条件を満たす唯一の$X$として定義されます。

$$
\sum \frac{1}{ 1+6.0^{ (X-A Perf_i )/ 400.0 } }=r-0.5 \tag{2}
$$

この$X$は二分探索を使用して計算できます。
順位は、同じ順位になった場合の平均となります。例えば、3位から6位まで4人が同じ場合、これらの人々の順位は4.5です。例外として、最初のコンテストでのパフォーマンスのばらつきが小さすぎるのを避けるため、最初のコンテストのパフォーマンスは以下のように誇張されます。

$$
Perf=(Perf- Center) \times 1.5+Center \tag{3}
$$

最後に、各ユーザーの$RPerf$は以下のように計算されます。

$$
RPerf=\min ( Perf, RATEDBOUND+400 ) \tag{4}
$$

ここで、$RATEDBOUND$はARCで2800、ABCで2000、AGCで∞です。
これは、ARCのいくつかのトップの人々のパフォーマンスがすべて3200であることを意味します。

レーティングの計算

レーティングはパフォーマンスの平均です。
以下の関数を$f$としましょう:

$$
F(n)=\frac{\sqrt{\sum_{i=1}^n 0.81^i}}{\sum_{i=1}^n 0.9^i} \tag{5}
$$

$$
f(n)=\frac{F(n)-F(\infty)}{F(1)-F(\infty)} \times 1200 \tag{6}
$$

次に、以下の関数を$g$とします:

$$
g(X)=2.0^{\frac{X}{800}} \tag{7}
$$

この関数は、より良いパフォーマンスにより多くの重みを割り当てるために使用されます。したがって、非常に良いパフォーマンスとそこそこのパフォーマンスとの間には大きな差がありますが、大失敗と中程度の失敗との間の差はそれほど大きくありません。
特定のユーザーの$RPerf$の履歴を$RPerf_1 , . . . , RPerf_k$としましょう。このユーザーのレーティングは、以下のように定義されます。

$$
Rating=g^{-1}\left(\frac{\sum_{i=1}^k g\left(RPer f_i\right) \times 0.9^i}{\sum_{i=1}^k 0.9^i}\right) \tag{8}
$$

この式により、各ユーザーのレーティングが計算されます。

補足

※ここは原文にない補足部分です。この補足がないと、実際のレーティングの算出ができません。ただし、公式の情報からでなく、推測であることの断りを入れておきます。

原文通りに計算すると、レーティング結果がどうしてもマイナスになってしまいます。そこで、400以下のレートを以下のようにマッピングすることで解決させます。

$$
mapRating(r) =
\begin{cases}
\frac{400}{\exp(\frac{400 - r}{400})} & ( r \leq 400 ) \\
r & ( r \gt 400 )
\end{cases} \tag{9}
$$

最後に、コンテストの出場回数$n$に応じてレーティングの信頼度を調整する$f(n)$の項(数式(6))を追加して、真のレーティングを計算します。

$$
TrueRating = mapRating(Rating - f(n)) \tag{10}
$$

--- 補足おわり ---


執筆中。

段と級

執筆中。現時点では、これが達成した最高のレーティングに依存するとだけ言っておきます。

このドキュメントの履歴

  • 2016年8月13日 Ver. 1.00:初版。
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1