Witaj!R - Optymalizacja prędkości i rankingi szachów
Próbuję obliczyć ranking szachowy graczy dla wielu graczy w 6 różnych umiejętnościach (C1, C2, ... C6). Mam ogromną ramkę danych (dane) gier, która wygląda na podobną (head (dane)). W tej grze jedna osoba (użytkownik) wybiera pomiędzy dwiema innymi osobami (p1/p2), aby wygrać.
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
w innej tabeli (old_users) I śledzenie wszystkich szachistów-score w 6 umiejętności (głowica (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
Algorytm Algorytm przebiega przez jeden danych wiersz na raz w pętli for, za każdym razem patrząc na i'th wiersz. Algorytm przyjrzy się wynikom p1 i p2, a następnie uzyska wynik dla dwóch graczy. Następnie obliczyć ich nowy wynik na podstawie tego, kto wygrywa lub przegrywa, a następnie aktualizuje komórkę old_users z odpowiadającymi jej nowymi rankingami.
Co muszę zrobić muszę to zrobić tak szybko jak to możliwe, z czym teraz 6000+ liniach dane dataframe tylko 24 graczy, to zajmuje trochę czasu, aby uruchomić poprzez.
Próbowałem czas mój obecny pętli for, co daje następujące czasy, które jest o wiele za dużo.
user system elapsed
104.72 0.28 118.02
Pytania
- Dlaczego ten algorytm trwa tak długo, aby uruchomić poprzez? Czy są jakieś polecenia, które są złe w pętlach for itp.?
- Jak mogę szybciej osiągnąć to, czego chcę?
Aktualny dla pętli
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
}
danych grać z
https://drive.google.com/file/d/0BxE_CHLUGoS0WlczUkxLM3VtVjQ/edit?usp=sharing
Każda pomoc jest bardzo cenione
Dziękujemy!
// HK
"Przegrany" nie "luźniejszy". W każdym razie, nie potrzebujesz "które", tylko zestawienie porównania. Wygląda to jak zadanie dla SQL, więc możesz rzucić okiem na pakiety 'sqldf' i podobne. –
Problem polega na tym, że każda nowa gra musi znać aktualny wynik meczu. To jest tylko problem szachowy. Więc jeśli w grze numer X gra się z niską wartością bieżącą, bije wynik z wysokim prądem. Wtedy osoba o niskim nominale zdobędzie więcej punktów za pobicie wyższego wyniku. – user4098307
W takim przypadku wystarczy uruchomić dwa wyszukiwania rekordów (po jednym dla każdego gracza) i do tego właśnie służy oprogramowanie bazy danych. –