AOYAMA Koji's プログラミングブログ - プログラミングを楽しく体験

モンテカルロ法による最適化アルゴリズム【スイスドロー対戦マッチングツール】プログラマー向け実装解説

2025/10/13
モンテカルロ法による最適化アルゴリズム【スイスドロー対戦マッチングツール】

 スイスドロー対戦マッチングツールにおける対戦表作成は、組み合わせ数が多く、また最適解が一意ではない可能性があるため、 最近のAIでも用いられる、モンテカルロ法による最適化アルゴリズムを用いて実現しました。 その具体的な手法を解説します。
 スイスドロー対戦マッチングツール(無料Webアプリ)はこちらからご利用いただけます。

プログラミングブログ記事一覧


[PR]


スイスドロー対戦マッチングの課題


 まず初めに、スイスドロー対戦マッチングツールにおける解決すべき課題を解説します。

重視すべき要素は勝敗数と重複対戦


 スイスドロー対戦マッチングでは重視すべき要素が2つあります。

同勝敗数優先

 スイスドローは勝者同士、敗者同士が対戦する方式です。 全勝、全敗だけでなく、その中間も含めて、勝敗数が同じ人同士が優先して対戦します。

重複対戦回避

 ひとつの大会において、同じ人と複数回当たることは、できるだけ回避すべきです。

両立しないケースの解決が課題


1回戦
2回戦
A
E
C
B
F
E
C
D
A
D
C
F
E
A
B
F
B
D
 しかしながら、同勝敗数対戦と重複対戦回避を同時に満たさないケースが存在します。


A(2-0) vs B(2-0)
C(1-1) vs D(1-1)
重複
E(0-2) vs F(0-2)
 例えば、6人が対戦して2勝、1勝1敗、2敗がそれぞれ2人いる状態で、 全勝同士と全敗同士は初対戦ですが、1勝1敗同士が重複対戦になる可能性があります。
 具体例はこの表のCさんとDさんです。
 これをどう解決するかが、スイスドロー対戦マッチングツールにおける課題です。

全勝者同士の対戦のみ必須で解決するケース


A(2-0) vs B(2-0)
C(1-1) vs F(0-2)
D(1-1) vs E(0-2)
 スイスドロー対戦において最重要視すべきは、全勝者同士の対戦です。
 そこで全勝者同士の対戦は必須とし、それ以下については勝敗数よりも重複対戦回避を優先することで、この表のように解決できる場合があります。

組み合わせ爆発問題


参加人数
組み合わせ数
6
15
16
200万+
32
19京+
 ただし、参加人数が多いと正解を見つけるまでにかなりのパターン数を調査する必要があります。 例えば6人なら全15パターンで調査可能ですが、16人で200万パターン、32人で19京パターンを超えます。
 このパターン数をすべて調査することは、計算時間がかかりすぎて現実的ではありません。

全勝者同士の対戦のみ必須でも解決できないケース


A(2-0) vs B(2-0)
C(1-1) vs D(1-1)
重複
3回戦棄権: E,F
 さらに、必須を全勝者同士の対戦のみとしても、重複対戦を回避できないケースがあります。 例えばEさんとFさんが3回戦を棄権した場合です。
 つまり、仮に全パターン調査できたとしても、そもそも「全勝者同士が対戦かつ重複対戦無し」の解があるとは限りません。

モンテカルロ法による最適化アルゴリズムとは


 この課題の解決に、モンテカルロ法による最適化アルゴリズムを用いました。
 モンテカルロ法とは、ランダムな試行を繰り返すことで問題の解を求める手法です。 完璧な解を保証するものではありませんが、現実的な時間で十分に良い解を得ることができます。
 本ツールのように、完璧な解があるか不明で、十分な解でも成立するケースでは、特に有用です。
 本ツールで具体的には、ランダムにマッチングさせた対戦表を複数作り、 その中から最適なものを選択する、という形で導入しました。

ランダムマッチングによる対戦表作成方法


 本ツールにおけるランダムマッチングによる対戦表作成方法を解説します。
 実際には完全なランダムではなく、全勝者同士が対戦することを優先する方式を採用しています。
  1. 勝敗数でプレイヤーをグループ化
  2. 最も勝数の多いグループのプレイヤーを取得
  3. 取り出されたプレイヤー同士を重複対戦しないようにランダムにマッチング
  4. 対戦が組めなかったら次に勝数の多いグループを取得して3へ戻りループ
  5. 取得可能なグループがなくなったら重複対戦は気にせず残りすべてランダムにマッチング

1.勝敗数でプレイヤーをグループ化


グループ
メンバー
2-0
A,B
1-1
C,D
0-2
E,F
 最初に勝敗数で各プレイヤーをグループ化します。

2.最も勝数の多いグループのプレイヤーを取得


対象
A,B
1-1
C,D
0-2
E,F
 まずは最も勝数の多いグループ(2-0)のプレイヤーを取り出してマッチング対象プレイヤーとします。

3.取り出されたプレイヤー同士を重複対戦しないようにランダムにマッチング


マッチ
A vs B
1-1
C,D
0-2
E,F
 対象プレイヤーを重複対戦にならないようにマッチングさせます。
 具体的には、各グループのプレイヤーをランダムな順序に並べ替えて対象に加え、対象の先頭から順に重複対戦にならない相手とペアを組んでいきます。

4.対戦が組めなかったら次に勝数の多いグループを取得して3へ戻りループ


(step1)1-1グループを取得→CとDは重複対戦

マッチ
A vs B
対象
C,D
0-2
E,F
 マッチング対象プレイヤーがいなくなりましたので、次のグループ(1-1)を取得します。 C,Dが対象になります。
 しかしCとDは重複対戦となりマッチングできません。


(step2)0-2グループ取得 → C,D,E,F が対象に

マッチ
A vs B
対象
C,D,E,F
 そこでさらに次のグループ(0-2)も取得します。 C,D,E,Fが対象になります。


(step3)ランダムマッチング → (例) CとEがマッチング成立

マッチ
A vs B
マッチ
C vs E
対象
D,F
 続けて重複対戦を避けてランダムにマッチングを組みます。 例として C と E がマッチングしたとしましょう。


(step4)DとFは重複で組めない → 5へ

 残りはDとFになりましたが、この2人は既に対戦していますので、次のグループを取得しようとしますが、ありません。
 そのため5に遷移します。

5.取得可能なグループがなくなったら重複対戦は気にせず残りすべてランダムにマッチング


マッチ
A vs B
マッチ
C vs E
マッチ
D vs F
重複
 取得できるグループがなくなったら、最後は重複は気にせずマッチングして完成です。

対戦表を複数作成して最適な対戦表を選ぶ


 本ツールでは前記の方法で対戦表を32種類作成します。 完成した対戦表それぞれに対してスコア付けを行い、最大スコアの対戦表を求めます。

対戦表のスコア付け


マッチ
履歴
スコア
A(2-0) vs B(2-0)
0
C(1-1) vs E(0-2)
-100
D(1-1) vs F(0-2)
重複
-1,100,100
合計
-1,100,200
 スコアは、各要素のスコアを合計して求めます。
 例えば勝敗数がズレていたら -100 点、重複対戦が発生していたら -1,100,000 点、といった具合です。 重複対戦は可能な限り避けたいため、非常に大きなペナルティとしています。
 前記の例は、合計 -1,100,200 点になります。
 なお、本ツールにはオプションとして、団体名や登録順によるマッチングしやすさ/しづらさがありますので、 必要に応じてそれもスコアに加算します。

最大スコアの対戦表を選択


モンテカルロ法による最適化アルゴリズム【スイスドロー対戦マッチングツール】 最適な対戦表の選出
 こうして作成しスコア付けされた対戦表の中から、最大スコア(最もマイナスの少ないもの)を選びます。 前記の例では、確率的にはほぼ確実に、重複が残らないこの対戦表が選出されます。
 以上がモンテカルロ法による最適化アルゴリズムを用いたスイスドロー対戦マッチングの対戦表の作成方法です。

[PR]

まとめ


 本記事ではスイスドロー対戦マッチングツールの具体的な対戦表作成方法および、 そこで採用したモンテカルロ法による最適化アルゴリズムについて解説しました。
 組み合わせ数が爆発し、最適解が一意ではない場合には、モンテカルロ法による最適化アルゴリズムはとても有用であることがわかります。 少しでもプログラマーの皆さんのお役に立てましたら幸いです。

補足

  • スイスドロー対戦マッチングツールの大幅リニューアルに合わせて本記事も2025年10月13日に内容を大幅変更しています。
  • 6人で15パターンというのは以下の通りです。順不同のため最初のペアは1人目を固定して問題なく、残り5人から1人選ぶので5パターン。次のペアは残り4人から1人目を固定して3パターン、残りのペアは確定で1パターン、これらを乗算して \(5 \times 3 \times 1 = 15\) パターンです。
  • 京(けい)は兆の1万倍です。
  • 対戦表を作成するパターン数の32に明確な根拠はありません。通常は数回で十分なパターンになることが多いので、処理負荷を上げない範囲で、それに対して十分な試行回数としました。現アルゴリズムなら一瞬で対戦表が作成されますので、回数を増やす余地はあります。
  • 「確率的にはほぼ確実に」と記載しましたが、この例で重複が残る確率は \( \frac{1}{4} \) であり、32回試行してすべて重複が残る確率は \( (\frac{1}{4})^{32} \approx 10^{-20} \) です。つまり重複が残らない確率は 99.9999…% 以上です。
  • 重複時スコア -1,100,000 は、まず、勝敗のズレ -100 が多くの組み合わせで発生して加算されても十分に差がある区切りの良い数字として-100万としました。その後オプションによりプラスのスコアを加えたためさらに-10万した値という経緯があります。
  • 最適な対戦表の例について下位2つの対戦順番は確率半分で入れ替わります。
  • 人数が奇数の場合は最後に余った人が不戦勝となります。本アルゴリズムでは勝数の少ない人(負数の多い人)が不戦勝になりやすいです。
  • 画像内のラスタライズ文字フォントにOpen Font LicenseNoto Sans Japaneseを使用しております。
  • 数式表現にMathJaxを使用しております。助かります!


カテゴリー:スイスドロー
[PR]