Frage zu Elo-System
-
Hi,
ich versuche momentan das Elo-System zu verstehen. Naja "eig." recht Simpel
Nun gut folgende Formel:
Rn = Ro + C * (S - Se) (1)
Rn = new rating
Ro = old rating
S = score (1.0)
Se = expected score (table)
C = constant----------------
Elo
diff Expected score
0 0.50
20 0.53
40 0.58
60 0.62
80 0.66
100 0.69
120 0.73
140 0.76
160 0.79
180 0.82
200 0.84
300 0.93
400 0.97
... ...
Table 1: Expected scoreEs gibt tausend von verschiedenen möglichkeiten für diff und die Expected score!!!
Nun Frage:
Wie berechne ich jedoch die Expected score ?
-
keine ahnung, ob es dir hilft, aber in der unverbesserlichen annahme, daß du letztendlich die mathematischen infos benutzen magst, um ein programm zu schreiben, puste ich mal meinen code:
#include "Tournier.h" #include <assert.h> #include <conio.h> #include <iostream> #include <fstream> #include <math.h> #include <stdlib.h> #include <windows.h> #include "Spielleiter.h" using namespace std; Spieler* Tournier::alleSpieler[MAX_ANZ]; int Tournier::spielerAnz=0; double siegWahrscheinlichkeit(double d) { return 1/(1+pow(10,-d/400)); } double verlustWahrscheinlichkeit(double d) { return 1-siegWahrscheinlichkeit(d); } void Tournier::anmelden(Spieler *spieler) { assert(spielerAnz<MAX_ANZ); spieler->eloPunkte=0; alleSpieler[spielerAnz]=spieler; ++spielerAnz; } void Tournier::abmelden(Spieler *spieler) { for(int i=0;i<spielerAnz;++i) { if(alleSpieler[i]==spieler) { --spielerAnz; alleSpieler[i]=alleSpieler[spielerAnz]; return; } } assert(0); } void Tournier::punkteLaden() { ifstream in("elo.txt"); while(in) { string name; double punkte; getline(in,name); in>>punkte; Spieler *s=getSpieler(name); if(s!=0) s->eloPunkte=punkte; getline(in,name); } if(getSpieler("Zufall")) getSpieler("Zufall")->eloPunkte=1000; } void Tournier::punkteSpeichern() { ofstream out("elo.txt"); for(int i=0;i<spielerAnz;++i) { if(alleSpieler[i]->getName()!="Test") { out<<alleSpieler[i]->getName()<<endl; out<<alleSpieler[i]->eloPunkte<<endl; } } } void Tournier::ranglisteZeigen() { ofstream out("rangliste.js"); out<<"document.write(\"<table border>\");\n"; out<<"document.write(\"<th>Rang</th>\");\n"; out<<"document.write(\"<th>elo-Punkte</th>\");\n"; out<<"document.write(\"<th>Name</th>\");\n"; out<<"document.write(\"<th>Autor</th>\");\n"; cout<<"Rangliste"<<endl; for(int i=0;i<spielerAnz;++i) if(alleSpieler[i]->eloPunkte!=0) { cout<<i+1<<". mit "<<int(alleSpieler[i]->eloPunkte)<<" elo-Punkten "<<alleSpieler[i]->getName()<<endl; out<<"document.write(\"<tr>\");\n"; out<<"document.write(\"<td>"<<i+1<<"</td>\");\n"; out<<"document.write(\"<td>"<<int(alleSpieler[i]->eloPunkte)<<"</td>\");\n"; out<<"document.write(\"<td>"<<alleSpieler[i]->getName()<<"</td>\");\n"; out<<"document.write(\"<td>"<<alleSpieler[i]->getAutor()<<"</td>\");\n"; out<<"document.write(\"</tr>\");\n"; } out<<"document.write(\"</table>\");\n"; cout<<endl; } void Tournier::punkteSortieren() { for(int i=0;i<spielerAnz-1;++i) for(int j=i+1;j<spielerAnz;++j) if(alleSpieler[i]->eloPunkte<alleSpieler[j]->eloPunkte) swap(alleSpieler[i],alleSpieler[j]); } void Tournier::neuBewertung(Spieler *spieler,bool show) { int spieleAnz=10; cout<<"Der Spieler "<<spieler->getName()<<" hat noch keine elo-Bewertung.\n"; cout<<"Er spielt jetzt gegen alle bereits bewerteten Spieler "<<spieleAnz<<" Spiele...\n"; double gesamtSumme=0; for(int s=0;s<spielerAnz;++s) { if(alleSpieler[s]->eloPunkte!=0) { double summe=0; Spielleiter spielleiter; for(int i=0;i<spieleAnz;++i) { int gewonnen; if(i>=spieleAnz/2) { gewonnen=spielleiter.start(spieler,alleSpieler[s],show,""); if(gewonnen==WEISS) summe+=1; else if(gewonnen==KEINER) summe+=0.5; else summe+=0; } else { gewonnen=spielleiter.start(alleSpieler[s],spieler,show,""); if(gewonnen==WEISS) summe+=0; else if(gewonnen==KEINER) summe+=0.5; else summe+=1; } cout<<alleSpieler[s]->getName()<<" "<<summe<<"/"<<i+1<<" \r"; } gesamtSumme+=summe; } cout<<endl; } double eloAlt=0,eloNeu=1000; while(int(eloAlt)!=int(eloNeu)) { double we=0; eloAlt=eloNeu; int gegner=0; for(s=0;s<spielerAnz;++s) { if(alleSpieler[s]->eloPunkte!=0) { we+=siegWahrscheinlichkeit(eloAlt-alleSpieler[s]->eloPunkte)*spieleAnz; } ++gegner; } eloNeu=eloAlt+(gesamtSumme-we)*800/(gegner*spieleAnz); } spieler->eloPunkte=eloNeu; punkteSortieren(); ranglisteZeigen(); } void Tournier::neuBewertungen(bool show) { for(int i=0;i<spielerAnz;++i) if(alleSpieler[i]->eloPunkte==0) neuBewertung(alleSpieler[i],show); } void Tournier::start(bool show) { SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_LOWEST); punkteLaden(); punkteSortieren(); ranglisteZeigen(); neuBewertungen(show); const int SPIELE=1000; int punkte[MAX_ANZ][MAX_ANZ]; {//Punkte auf 0 setzen for(int n1=0;n1<spielerAnz;++n1) for(int n2=0;n2<spielerAnz;++n2) punkte[n1][n2]=0; } {//Tournier durchführen //cout<<"Tournier"<<endl; Spielleiter spielleiter; for(int n1=0;n1<spielerAnz;++n1) { Spieler *s1=alleSpieler[n1]; for(int n2=0;n2<spielerAnz;++n2) { Spieler *s2=alleSpieler[n2]; if(n1!=n2) { for(int i=0;i<SPIELE/2;++i) { int ergebnis=spielleiter.start(s1,s2,show,""); if(show) Sleep(1000); punkte[n1][n2]+=1+ergebnis; punkte[n2][n1]+=1-ergebnis; } cout<<punkte[n1][n2]/2.0<<'\t'; } else cout<<"-\t"; } cout<<endl; } } double eloPunkteNeu[MAX_ANZ]; { const double k=.1;//200.0/(20+SPIELE); for(int n1=0;n1<spielerAnz;++n1) { double w=0,we=0; for(int n2=0;n2<spielerAnz;++n2) { if(n2!=n1) { w+=punkte[n1][n2]/2.0; we+=siegWahrscheinlichkeit(alleSpieler[n1]->eloPunkte-alleSpieler[n2]->eloPunkte)*SPIELE; } } eloPunkteNeu[n1]=alleSpieler[n1]->eloPunkte+(w-we)*k; } } { for(int n1=0;n1<spielerAnz;++n1) { alleSpieler[n1]->eloPunkte=eloPunkteNeu[n1]; if(alleSpieler[n1]->getName()=="Zufall") alleSpieler[n1]->eloPunkte=1000; } } punkteSortieren(); ranglisteZeigen(); punkteSpeichern(); }
-
Hi,
thx!
Hät auch das gereicht ! ..
double siegWahrscheinlichkeit(double d)
{
return 1/(1+pow(10,-d/400));
}Cu
-
Jayson schrieb:
Hät auch das gereicht ! ..
double siegWahrscheinlichkeit(double d)
{
return 1/(1+pow(10,-d/400));
}ok.
die formel ist nicht total genau exakt. für was total genaues, hätte ich ich dieses komische ∫-zeichen gebraucht, und da weiß ich nicht, wie die c++-funktion heißt.