我正在寻找一个函数,该函数可以计算与国际象棋游戏相关的真实Elo性能等级。
它将接收:
game_results的向量,例如[1 0 0.5]表示玩家赢得了第一场比赛,输了第二场比赛,并吸引了第三场比赛。由此,我们将获得另一个可变分数,即1.5,以及另一个可变num_games,其为3。
对手评分的向量,例如[1200 1400 1350]表示第一个对手的评分为1200,第二个对手的评分为1,350,第三者为1350。
我知道以下等式中的真实性能等级为x:
for i = 1:num_games
score = score + (1/(1+10^((opp_ratings(i)-x)/400)));
end
需要的是找到正确的x
值,使此处的分数加起来等于实际分数1.5。
在这里我碰巧知道x=1317.55
会产生大约正确的答案。
在我看来,我需要将包含上面代码的匿名函数传递给其他优化函数。但是:
我从this answer了解到,匿名函数不能包含循环。
我不确定哪种优化功能合适。 MATLAB似乎没有任何本地二等分函数。
答案 0 :(得分:2)
您可以使用诸如fsolve
之类的非线性方程求解器。
fsolve
将为方程x
找到f(x) == 0
的值。
因此,您可以创建函数f(x)
并运行fsolve
:
opp_ratings = [1200 1400 1350];
tot_score = 1.5
f = @(x) sum(1./(1+10.^((opp_ratings-x)/400)))-tot_score;
res = fsolve(f,0) %the second argument is the initial point x0
% res = 1317.6
注意到我已经使用运算符.^
(元素明智的幂运算符)和./
(元素明智除法)线性化了您的for循环。因此,现在更容易定义单行方程f(x)
。
这也是一个细节,但是为了提高fsolve性能(减少所需的迭代次数),您可以例如将初始x0值设置为等于“平均ELO等级”,例如1000。所以{{1} }在统计上会更快收敛。
不推荐使用
:如果您的方程无法线性化,那么您确实可以这样写fsolve(f,1000)
:
f(x)
使用arrayfun。但是,如果可能的话,请避免使用此解决方案(因为它很丑,而且速度稍慢)。