不同编程语言复现ELO匹配机制与机制原理理解

news2024/10/10 18:28:51

本章概述

从数学角度分析 分别用c java python演示算法机制

数学理论

预期胜率计算公式

积分算法

  • 为什么排位比以前更难?
    • elo使玩家尽量其股相当 双方实力进来保证持平
    • elo算法基于预先假设:
      • 一名选手的当前实力受各种因素的影响会在一定范围内波动,某个时刻的用来描述其实力的函数应当符合正态分布

      • 在这里插入图片描述

      • 两名选手进行对战时的预期胜率

      • 在这里插入图片描述

      • 在这里插入图片描述

分数迭代公式

  • 以上积分公式只能看出来一个预期范围 如果想确定一名选手的准确"elo表现分"还需要总结出另外一个公式
参数含义
Rn玩家比赛结束后的新的排位分值
Ro比赛前玩家的排位分
K一个加成系数,由玩家当前分值水平决定(分值越高K越小)
W玩家实际对局结果得分(赢=1,输=0)
P(D)预期胜率
RaA选手当前分数
RbB选手当前分数
Rn = Ro +K* (W - P(D))
  • 预期A选手的胜负值
Ea = 1/(1+10^ [(Rb-Ra)/400])
  • 预期B选手的胜负值
Eb = 1/(1+10^ [(Ra-Rb)/400])

c

#include <bits/stdc++.h>
using namespace std;

void updateRatingUsingELoRating(float rating1, float rating2, int ratingConstant, bool player1SuccessProb) {

   float P1, P2;
   if(rating1 > rating2){
      P1 = (1.0 / (1.0 + pow(10.0, ((rating1 - rating2) / 400.0)) ) );
      P2 = 1 - P1;
   }
   else {
      P2 = (1.0 / (1.0 + pow(10.0, ((rating2 - rating1) / 400.0)) ) );
      P1 = 1 - P2;
   }

   if (player1SuccessProb == 1) {
      rating1 = rating1 + ratingConstant * (1 - P1);
      rating2 = rating2 + ratingConstant * (0 - P2);
   }
   else {
      rating1 = rating1 + ratingConstant * (0 - P1);
      rating1 = rating1 + ratingConstant * (1 - P2);
   }

   cout<<"Ratings After the game\n";
   cout<<"Player 1 : "<<rating1<<"\t Player 2 : "<<rating2;
}

int main()
{
   float rating1 = 782, rating2 = 1432;
   int ratingConstant = 100;
   bool player1SuccessProb = 1;
   cout<<"Ratings before the game: \n";
   cout<<"Player 1 : "<<rating1<<"\t Player 2 : "<<rating2<<endl;
   if(player1SuccessProb)
      cout<<"Player 1 wins the game!\n";
   else
      cout<<"Player 2 wins the game!\n";
   updateRatingUsingELoRating(rating1, rating2, ratingConstant, player1SuccessProb);

   return 0;
}

c++

使用Elo评级差异计算每个玩家获胜的概率。玩家A战胜玩家B的概率可以用公式来计算:P(A) = 1 / (1 + pow(10, (ratingB - ratingA) / 400))。同样,玩家B战胜玩家A的概率为:P(B) = 1 / (1 + pow(10, (ratingA - ratingB) / 400))。(来源:GeeksforGeeks)

确定游戏的实际结果。如果玩家A获胜,则实际得分为1。如果玩家B获胜,则实际得分为0。

根据实际结果和预期结果更新两名球员的评分。玩家A的新评分可以使用以下公式计算:newRatingA = ratingA + K * (actualScoreA - expectedScoreA),其中K是代表评分变化幅度的常数。玩家B的新评级也可以类似地计算出来。(来源:GeeksforGeeks)
Calculate the probabilities of winning for each player using the Elo rating difference. The probability of player A winning against player B can be calculated using the formula: P(A) = 1 / (1 + pow(10, (ratingB - ratingA) / 400)). Similarly, the probability of player B winning against player A is: P(B) = 1 / (1 + pow(10, (ratingA - ratingB) / 400)). (Source: GeeksforGeeks)

Determine the actual outcome of the game. If player A wins, the actual score is 1. If player B wins, the actual score is 0.

Update the ratings of both players based on the actual outcome and the expected outcome. The new rating for player A can be calculated using the formula: newRatingA = ratingA + K * (actualScoreA - expectedScoreA), where K is a constant representing the magnitude of rating changes. The new rating for player B can be calculated similarly. (Source: GeeksforGeeks)

#include <iostream>
#include <cmath>

// Function to calculate the probability of winning for player A
float Probability(int ratingA, int ratingB) {
    return 1.0 / (1.0 + std::pow(10, (ratingB - ratingA) / 400.0));
}

// Function to update Elo ratings based on the outcome of the game
void EloRating(int& ratingA, int& ratingB, int K, int actualScoreA) {
    float expectedScoreA = Probability(ratingA, ratingB);
    float expectedScoreB = 1 - expectedScoreA;

    ratingA += K * (actualScoreA - expectedScoreA);
    ratingB += K * ((1 - actualScoreA) - expectedScoreB);
}

int main() {
    int ratingA = 1200;
    int ratingB = 1000;
    int K = 30;
    int actualScoreA = 1;

    EloRating(ratingA, ratingB, K, actualScoreA);

    std::cout << "Updated Ratings:\n";
    std::cout << "Player A: " << ratingA << "\n";
    std::cout << "Player B: " << ratingB << "\n";

    return 0;
}
#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate the Probability
float Probability(int rating1, int rating2)
{
    return 1.0 * 1.0 / (1 + 1.0 * pow(10, 1.0 * (rating1 - rating2) / 400));
}
 
// Function to calculate Elo rating
// K is a constant.
// d determines whether Player A wins or Player B.
void EloRating(float Ra, float Rb, int K, bool d)
{
    // To calculate the Winning Probability of Player B
    float Pb = Probability(Ra, Rb);
 
    // To calculate the Winning Probability of Player A
    float Pa = Probability(Rb, Ra);
 
    // Case -1 When Player A wins
    // Updating the Elo Ratings
    if (d == 1) {
        Ra = Ra + K * (1 - Pa);
        Rb = Rb + K * (0 - Pb);
    }
 
    // Case -2 When Player B wins
    // Updating the Elo Ratings
    else {
        Ra = Ra + K * (0 - Pa);
        Rb = Rb + K * (1 - Pb);
    }
 
    cout << "Updated Ratings:-\n";
    cout << "Ra = " << Ra << " Rb = " << Rb;
}
 
// Driver code
int main()
{
    // Ra and Rb are current ELO ratings
    float Ra = 1200, Rb = 1000;
 
    int K = 30;
    bool d = 1;
 
    // Function call
    EloRating(Ra, Rb, K, d);
 
    return 0;
}

java

To implement the ELO algorithm for game matchmaking in Java

Define the ELO rating system: The ELO rating system is a widely used algorithm to rank players in competitive games. It assigns players a skill level based on their performance in matches. The ELO rating is updated after each match based on the outcome and the expected probability of winning.

Calculate the expected probability of winning: Before a match, you need to calculate the expected probability of winning for each player. This can be done using the following formula:

P1 = 1 / (1 + Math.pow(10, (rating2 - rating1) / 400));
P2 = 1 / (1 + Math.pow(10, (rating1 - rating2) / 400));

Where rating1 and rating2 are the ELO ratings of the two players.

Update the ratings after the match: After the match is finished, you need to update the ELO ratings of the players based on the actual outcome and the expected probability of winning. The formula for updating the ratings is:
rating1 = rating1 + K * (actual - expected);
rating2 = rating2 + K * (actual - expected);

Where actual is the actual outcome of the match (0 for a loss, 1 for a win), expected is the expected probability of winning calculated in step 2, and K is a constant that determines the magnitude of rating changes.

public class EloMatchmaking {
    public static void main(String[] args) {
        int rating1 = 1200;
        int rating2 = 1000;
        int K = 30;

        double P1 = 1 / (1 + Math.pow(10, (rating2 - rating1) / 400));
        double P2 = 1 / (1 + Math.pow(10, (rating1 - rating2) / 400));

        // Suppose player 1 wins
        double actual = 1;
        double expected = P1;

        rating1 = (int) (rating1 + K * (actual - expected));
        rating2 = (int) (rating2 + K * (actual - expected));

        System.out.println("Updated ratings:");
        System.out.println("Player 1: " + rating1);
        System.out.println("Player 2: " + rating2);
    }
}

c#

public class EloRating
{
    private const int K = 20;

    public static void UpdateEloRating(ref int rating1, ref int rating2, bool isFirstPlayerWin)
    {
        int delta = CalculateRatingChange(rating1, rating2, isFirstPlayerWin ? 1 : 0);
        rating1 += delta;
        rating2 -= delta;
    }

    private static int CalculateRatingChange(int rating1, int rating2, int actualScore)
    {
        double expectedScore = 1 / (1 + Math.Pow(10, (rating2 - rating1) / 400.0));
        return (int) (K * (actualScore - expectedScore));
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/790187.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【VUE】vue3 SFC方式实现九宫格效果

效果图 调用方式 <template><grid class"grid-demo" isScale><grid-item class"grid-demo-item">1</bg-grid-item><grid-item class"grid-demo-item">2</bg-grid-item><grid-item class"grid-demo…

索引的数据结构

索引的数据结构 部分资料来自B站尚硅谷-宋红康老师 1. 为什么使用索引 使用索引是为了加快数据库的查询速度和提高数据库的性能。索引是数据库表中的一种数据结构&#xff0c;它可以帮助数据库快速定位并检索所需的数据。 当数据库表中的数据量较大时&#xff0c;如果没有索…

Training-Time-Friendly Network for Real-Time Object Detection 论文学习

1. 解决了什么问题&#xff1f; 目前的目标检测器很少能做到快速训练、快速推理&#xff0c;并同时保持准确率。直觉上&#xff0c;推理越快的检测器应该训练也很快&#xff0c;但大多数的实时检测器反而需要更长的训练时间。准确率高的检测器大致可分为两类&#xff1a;推理时…

uni-app:实现账号密码登录,并且实现当页面登录过该账号在下次登录时无需再输入账号密码(本地缓存实现)

效果 前端代码 一、完整代码 <template><view><view class"all"><view class"title"><image :src"title_login" alt"图片损坏" /></view><form class"login-form" submit"fo…

JAVA面试总结-Redis篇章(二)——缓存击穿

JAVA面试总结-Redis篇章&#xff08;二&#xff09; 缓存击穿解决方案一&#xff1a;互斥锁解决方案二&#xff1a;逻辑过期![在这里插入图片描述](https://img-blog.csdnimg.cn/176dfab3e26044a9a730fabea4314e8e.png) 缓存击穿 解决方案一&#xff1a;互斥锁 解决方案二&…

SpringBoot-5

Spring Boot 的项目属性配置 在项目中很多时候需要用到一些配置的信息&#xff0c;这些信息可能在测试环境和生产环境下会有不同的配置&#xff0c;后面根据实际业务情况有可能还会做修改&#xff0c;针对这种情况不能将这些配置在代码中写死&#xff0c;最好就是写到配置文件…

Rust vs Go:常用语法对比(六)

题图来自[1] 101. Load from HTTP GET request into a string Make an HTTP request with method GET to URL u, then store the body of the response in string s. 发起http请求 package mainimport ( "fmt" "io/ioutil" "net" "net/http…

Fiddler使用说明及中文绿化版

Fiddler是最常用的Web调试工具之一。 对于开发来说&#xff0c;前端可以通过fiddler代理来调试JS、CSS、HTML样式。后端可以通过fiddler查看请求和相应&#xff0c;定位问题。 对于测试来说&#xff0c;可以通过抓包方式修改前端请求参数和模拟后端返回&#xff0c;快速定位缺…

Pr LOGO平滑过渡效果

哈喽&#xff0c;各位小伙伴&#xff01;今天我们来学习一下如何制作LOGO平滑过渡效果&#xff1f; 准备工作 两个透明LOGO&#xff0c;一个水滴音效 ​新建序列 新建一个1920*1080的序列&#xff0c;将图片拖拽至轨道 CtrlR 图片时长设置为3SCtrlD 快速添加过渡效果右键…

【Python】生成md5码

目录 1 代码 2 运行结果 使用hashlib库来生成md5码。如下代码会生成Happy every day的md5哈希值。 1 代码 import hashlibdef generate_md5(string):md5 hashlib.md5()md5.update(string.encode(utf-8))return md5.hexdigest()if __name__ __main__:MD5 generate_md5(&qu…

测试开源C#人脸识别模块ViewFaceCore(3:人脸特征提取和对比)

ViewFaceCore模块的FaceRecognizer支持人脸特征提取和对比&#xff0c;将人脸中的关键信息转换为矢量信息&#xff0c;然后通过计算两个矢量的相似度以判断人脸的相似程序。   调用FaceRecognizer对比人脸相似度主要包括以下步骤&#xff1a;   1&#xff09;调用faceDetec…

第一百一十六天学习记录:C++提高:STL-string(黑马教学视频)

string基本概念 string是C风格的字符串&#xff0c;而string本质上是一个类 string和char区别 1、char是一个指针 2、string是一个类&#xff0c;类内部封装了char*&#xff0c;管理这个字符串&#xff0c;是一个char型的容器。 特点&#xff1a; string类内部封装了很多成员方…

idea社区版(2023.1)设置spring boot项目热启动

热启动 在开发过程中&#xff0c;当写完一个功能我们需要运行应用程序测试时需要重启服务器&#xff0c;一个最简单的项目也要花费10多秒&#xff0c;如果是更大的项目则耗时更多。SpringBoot提供了spring-boot-devtools&#xff0c;使得项目在发生改动时能够自动重启应用 id…

hadoop3编译安装

1.参考资料 官方的https://github.com/apache/hadoop/blob/trunk/BUILDING.txt 2.编译环境 Linux系统&#xff1a;Centos7.2 Jdk版本&#xff1a;jdk1.8 cmake版本&#xff1a;3.19 Hadoop版本&#xff1a;3.1.2 Maven版本&#xff1a;3.6.3 Protobuf版本&#xff1a;2…

【数据分析专栏之Python篇】二、Jupyer Notebook安装配置及基本使用

文章目录 前言一、Jupter Notebook是什么1.1 简介1.2 组成部分1.3 Jupyter Notebook的主要特点 二、为什么使用Jupyter Notebook?三、安装四、Jupyter Notebok配置4.1 基本配置4.2 配置开机自启与后台运行4.3 开启代码自动补全 五、两种键盘输入模式5.1 编辑模式5.2 命令模式5…

J2EE通用分页02

目录 一.重构-提取公用方法 1.为了进行公共方法的抽取&#xff0c;需要找出上面实习中的可通用部分&#xff0c;和差异化部分 2.公用方法封装思路 3. 具体实现 二.分页标签 2.1 准备一个Servlet 3.2 结果展示页面 三. 过滤器解决中文乱码问题 四.加入分页功能 四…

Qt Core学习日记——第七天QMetaObject(上)

每一个声明Q_OBJECT的类都具有QMetaObject对象 Q_OBJECT宏源代码&#xff1a; #define Q_OBJECT \ public: \ QT_WARNING_PUSH \ Q_OBJECT_NO_OVERRIDE_WARNING \ static const QMetaObject staticMetaObject; \ virtual const QMetaObject *metaObject() const; \ vir…

Rust vs Go:常用语法对比(五)

题图来自 Rust vs Go 2023[1] 81. Round floating point number to integer Declare integer y and initialize it with the rounded value of floating point number x . Ties (when the fractional part of x is exactly .5) must be rounded up (to positive infinity). 按规…

垃圾回收标记阶段算法

1.标记阶段的目的 主要是在GC在前&#xff0c;判断出哪些是有用的对象&#xff0c;哪些是需要回收的对象&#xff0c;只有被标记为垃圾对象&#xff0c;GC才会对其进行垃圾回收。判断对象是否为垃圾对象的两种方式&#xff1a;引用计数算法和可达性分析算法。 2.引用计数算法…

MySQL基础(一)

目录 前言 一、概述 1.什么是数据库 2.数据库能干什么 3.为什么要用数据库&#xff0c;优势、特性 二、数据库类型 &#xff08;一&#xff09;、关系型数据库&#xff0c;RDBMS 1.概述 2.特点 3.代表产品 &#xff08;二&#xff09;、非关系型数据库&#xff0c;No…