This repository has been archived by the owner on Apr 17, 2024. It is now read-only.
THUAI4 天梯折合算法 #86
Timothy-Liuxf
started this conversation in
Show and tell
Replies: 2 comments 1 reply
-
欢迎各位随时贡献有关天梯分数计算方法的点子并提出 issue 或在下方评论 |
Beta Was this translation helpful? Give feedback.
0 replies
-
今年把得分上限这个东西去掉了。理论上今年可以得很高很高分,但是我估计大部分比赛得分在400-600左右,最高估计1000左右。算法 借 鉴 了THUAI4,算法,换了个激活函数(正态CDF),感觉分数变化相对更好了一些? #include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
template <typename T>
using mypair = pair<T, T>;
double PHI(double x) // THUAI3: Sigmoid; THUAI4: Tanh; THUAI5: Normal Distribution CDF
{
//double a1 = 0.2548292592;
//double a2 = -0.284496736;
//double a3 = 1.421413741;
//double a4 = -1.453152027;
//double a5 = 1.061405429;
//double p = 0.3275911;
//int sign = 1;
//if (x < 0)
// sign = -1;
//x = fabs(x) / sqrt(2.0);
//double t = 1.0 / (1.0 + p * x);
//double y = 1.0 - ((((((a5 * t + a4) * t + a3) * t) + a2) * t) + a1) * t * exp(-x * x);
//double cdf = 0.5 * (1.0 + sign * y);
//return (cdf - 0.5) * 2.0; // 化到[-1,1]之间
return erf(x / sqrt(2));
}
// orgScore 是天梯中两队的分数;competitionScore 是这次游戏两队的得分
mypair<int> cal(mypair<int> orgScore, mypair<int> competitionScore)
{
// 调整顺序,让第一个元素成为获胜者,便于计算
bool reverse = false; // 记录是否需要调整
if (competitionScore.first < competitionScore.second)
{
reverse = true;
}
else if (competitionScore.first == competitionScore.second)
{
if (orgScore.first == orgScore.second) // 完全平局,不改变天梯分数
{
return orgScore;
}
if (orgScore.first > orgScore.second) // 本次游戏平局,但一方天梯分数高,另一方天梯分数低,需要将两者向中间略微靠拢,因此天梯分数低的定为获胜者
{
reverse = true;
}
else
{
reverse = false;
}
}
if (reverse) // 如果需要换,换两者的顺序
{
swap(competitionScore.first, competitionScore.second);
swap(orgScore.first, orgScore.second);
}
// 转成浮点数
mypair<double> orgScoreLf;
mypair<double> competitionScoreLf;
orgScoreLf.first = orgScore.first;
orgScoreLf.second = orgScore.second;
competitionScoreLf.first = competitionScore.first;
competitionScoreLf.second = competitionScore.second;
mypair<int> resScore;
const double deltaWeight = 90.0; // 差距悬殊判断参数,比赛分差超过此值就可以认定为非常悬殊了,天梯分数增量很小,防止大佬虐菜鸡的现象造成两极分化
double delta = (orgScoreLf.first - orgScoreLf.second) / deltaWeight;
cout << "Normal CDF delta: " << PHI(delta) << endl;
{
const double firstnerGet = 3e-4; // 胜利者天梯得分权值
const double secondrGet = 1e-4; // 失败者天梯得分权值
double deltaScore = 100.0; // 两队竞争分差超过多少时就认为非常大
double correctRate = (orgScoreLf.first - orgScoreLf.second) / 100.0; // 订正的幅度,该值越小,则在势均力敌时天梯分数改变越大
double correct = 0.5 * (PHI((competitionScoreLf.first - competitionScoreLf.second - deltaScore) / deltaScore - correctRate) + 1.0); // 一场比赛中,在双方势均力敌时,减小天梯分数的改变量
resScore.first = orgScore.first + round(competitionScoreLf.first * competitionScoreLf.first * firstnerGet * (1 - PHI(delta)) * correct); // 胜者所加天梯分
if (competitionScoreLf.second < 1000)
resScore.second = orgScore.second - round((1000.0 - competitionScoreLf.second) * (1000.0 - competitionScoreLf.second) * secondrGet * (1 - PHI(delta)) * correct); // 败者所扣天梯分
else
resScore.second = orgScore.second; // 败者拿1000分,已经很强了,不扣分
}
// 如果换过,再换回来
if (reverse)
{
swap(resScore.first, resScore.second);
}
return resScore;
}
void Print(mypair<int> score)
{
std::cout << " team1: " << score.first << std::endl
<< "team2: " << score.second << std::endl;
}
int main()
{
int x, y;
std::cout << "origin score of team 1 and 2: " << std::endl;
std::cin >> x >> y;
auto ori = mypair<int>(x, y);
std::cout << "game score of team 1 and 2: " << std::endl;
std::cin >> x >> y;
auto sco = mypair<int>(x, y);
Print(cal(ori, sco));
} |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
关于根据队式每场比赛的分数映射到天梯分数的问题:
队式比赛为两队对战,每队得分的区间均为 [0, 2500]。
以 tanh 函数为基础进行设计。
设计原则如下:
上述原则可以保证以下两个目的的达成:
用 cpp 代码编写算法代码如下(
cal
函数):特别注意:此算法是在 THUAI4 的比赛直接得分封顶为 2500 分、最低不低于 0 分的前提下设计的,因此并不一定适用于 THUAI5 的情形。
Beta Was this translation helpful? Give feedback.
All reactions