Hallo zusammen!R - Geschwindigkeitsoptimierung und Chess Rankings
Ich versuche, Spieler Schach-Rankings für eine Reihe von Spielern in 6 verschiedenen Fähigkeiten (C1, C2, ... C6) zu berechnen. Ich habe einen riesigen Datenrahmen (Daten) von gespielten Spielen, der ähnlich aussieht (Kopf (Daten)). In diesem Spiel wählt eine Person (Benutzer) zwischen zwei anderen Personen (p1/p2), um zu gewinnen.
row.names user p1 p2 skill win looser time
---------------------------------------------------------
2 KE CL HK C1 CL HK 433508371
25 KE HK JT c1 HK JT 433508401
35 KE AB JT C1 AB JT 433508444
110 NF IP HE C1 HE IP 433508837
78 NF IP AS C1 AS IP 433508848
82 NF IT CV C1 CV IT 433508860
In einer anderen Tabelle (old_users) Ich behalte den Überblick über alle Schach Partituren Spieler in den sechs Fähigkeiten (Kopf (old_users))
user C1 C2 C3 C4 C5 C6
1 BD 1200 1200 1200 1200 1200 1200
2 NF 1200 1200 1200 1200 1200 1200
3 CH 1200 1200 1200 1200 1200 1200
4 AR 1200 1200 1200 1200 1200 1200
5 AS 1200 1200 1200 1200 1200 1200
6 MS 1200 1200 1200 1200 1200 1200
Der Algorithmus Der Algorithmus läuft durch einen Daten reihe zu einem zeitpunkt in einer for-schleife, jedes mal in der i-ten reihe. Der Algorithmus sucht die Score-Daten von p1 und p2, retrive die Punkte der beiden Spieler für die gespielte Fähigkeit. Berechnen Sie dann ihre neue Punktzahl basierend darauf, wer gewinnt oder verliert, und aktualisieren Sie dann die old_users-Zelle mit den entsprechenden neuen Rankings.
Was benötige ich ich tun muss dies so schnell wie möglich zu tun und mit den Datenrahmen Daten sind jetzt 6000+ Linien für nur 24 Spieler dauert es eine Weile durchlaufen.
Ich habe versucht, meine aktuelle for-Schleife Zeit zu geben, die die folgenden Zeiten gibt, die viel zu viel ist.
user system elapsed
104.72 0.28 118.02
Fragen
- Warum dauert dieser Algorithmus so lange durchlaufen? Gibt es irgendwelche Befehle, die in For-Schleifen usw. nicht gut sind?
- Wie erreiche ich schneller, was ich will?
Aktuelle for-Schleife
for (i in 1:dim(data)[1]) {
tmp_data<-data[i,] #Take the i'th row in data
score_col<-which(colnames(old_users)==tmp_data$skill) #find old_user column which matched the skill played
winners_old_data<-old_users[which(old_users$user==tmp_data$win),] #Fetch winner's old scores
loosers_old_data<-old_users[which(old_users$user==tmp_data$looser),] #Fetch looser's old scores
winners_new_score=winners_old_data[score_col]+(32/2)*(1-0+(1/2)*((loosers_old_data[score_col]-winners_old_data[score_col])/200)) #Calculate the winner's new score
loosers_new_score=loosers_old_data[score_col]+(32/2)*(0-1+(1/2)*((winners_old_data[score_col]-loosers_old_data[score_col])/200)) #Calculate the looser's new score
old_users[old_users$user==winners_old_data[[1]],score_col]<-winners_new_score #update cell in old_users
old_users[old_users$user==loosers_old_data[[1]],score_col]<-loosers_new_score #update cell in old_users
}
Daten mit
https://drive.google.com/file/d/0BxE_CHLUGoS0WlczUkxLM3VtVjQ/edit?usp=sharing
Jede Hilfe ist sehr viel
geschätzt zu spielenVielen Dank!
// HK
"Verlierer" nicht "loser". Wie auch immer, du brauchst nicht das 'was', nur die Vergleichsaussage. Das sieht nach einem Job für SQL aus, also sollten Sie sich die Pakete 'sqldf' und ähnliche Pakete ansehen. –
Das Problem ist, dass Sie für jedes neu gespielte Spiel den aktuellen Spielerstand der übereinstimmenden Spieler kennen müssen. Das ist genau das Schachproblem. Wenn also im Spiel Nummer X ein mit einem niedrigen aktuellen Punktestand gespielt wird, wird ein mit einem hohen aktuellen Punktestand gespielt. Dann erhält die Person mit niedriger Bewertung mehr Punkte, um die höhere Punktzahl zu schlagen. – user4098307
In diesem Fall müssen Sie nur zwei Datensatzsuchen (eine für jeden Player) ausführen, und dafür ist die Datenbanksoftware zuständig. –