2014-10-01 6 views
5

हाय वहाँ!आर - स्पीड अनुकूलन और शतरंज रैंकिंग

मैं 6 अलग-अलग कौशल (सी 1, सी 2, ... सी 6) में कई खिलाड़ियों के लिए खिलाड़ियों शतरंज रैंकिंग की गणना करने की कोशिश कर रहा हूं। मेरे पास खेले जाने वाले गेम का एक बड़ा डेटाफ्रेम (डेटा) है जो इसे पसंद करता है (सिर (डेटा))। इस खेल में एक व्यक्ति (उपयोगकर्ता) जीतने के लिए दो अन्य लोगों (पी 1/पी 2) के बीच चयन करता है।

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 

एक और तालिका में (old_users) मैं 6 कौशल में सभी खिलाड़ियों को शतरंज अंकों का लेखा रखने (सिर (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          

एल्गोरिथ्म एल्गोरिथ्म डेटा एक के माध्यम से चलाता है फॉर-लूप में एक समय में पंक्ति, हर बार जब मैं पंक्ति पर देखता हूं। एल्गोरिदम पी 1 और पी 2 के स्कोर डेटा को देखेगा, कौशल के लिए दो खिलाड़ियों के स्कोर को दोबारा हासिल करें। फिर जीतने या खोने के आधार पर अपने नए स्कोर की गणना करें और फिर संबंधित नई रैंकिंग के साथ old_users सेल को अपडेट करें।

मैं मैं संभव के रूप में तेजी से ऐसा करने की जरूरत क्या करने की जरूरत है, और dataframe डेटा केवल 24 खिलाड़ियों के लिए अब 6000 + लाइनों होने के साथ इसके माध्यम से चलाने के लिए कुछ समय लगता है।

मैंने अपने वर्तमान फॉर-लूप को समय देने का प्रयास किया है जो निम्नलिखित समय देता है जो बहुत अधिक है।

user system elapsed 
104.72  0.28 118.02 

प्रश्न

  1. क्यों इस एल्गोरिथ्म तो लंबे समय के माध्यम से चलाने के लिए ले करता है? क्या कोई ऐसा आदेश है जो फॉर-लूप इत्यादि के अंदर है।
  2. मैं तेज़ी से क्या हासिल करना चाहता हूं?

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 
     } 

डाटा

https://drive.google.com/file/d/0BxE_CHLUGoS0WlczUkxLM3VtVjQ/edit?usp=sharing

साथ खेलने के लिए वर्तमान के लिए लूप किसी भी मदद की बहुत सराहना की है

धन्यवाद!

// एच

+0

"हारने वाला" नहीं "looser"। वैसे भी, आपको 'जो' की आवश्यकता नहीं है, केवल तुलनात्मक बयान। यह एसक्यूएल के लिए नौकरी की तरह दिखता है, इसलिए आप 'sqldf' और इसी तरह के पैकेजों पर एक नज़र डालना चाहेंगे। –

+1

समस्या यह है कि आपको खेले गए प्रत्येक नए गेम के लिए मिलान किए गए खिलाड़ियों के वर्तमान स्कोर को जानने की आवश्यकता है। यह बेहद शतरंज-समस्या है। तो अगर खेल संख्या एक्स में एक कम वर्तमान स्कोर के साथ खेला जाता है तो एक उच्च वर्तमान स्कोर के साथ खेला जाता है। फिर निम्न-रेटेड व्यक्ति को उच्च स्कोर को मारने के लिए और अधिक अंक प्राप्त होंगे। – user4098307

+1

इस मामले में आपको केवल दो रिकॉर्ड-खोज (प्रत्येक खिलाड़ी के लिए एक) चलाने की आवश्यकता है, और यही वह डेटाबेस सॉफ़्टवेयर है। –

उत्तर

2

डेटा तुम्हें तैनात हास्यास्पद छोटा है! सोचने के लिए मुझे इसे अनार करने के लिए कुछ इंस्टॉल करना था ...! यदि आप कृपया एक बड़ा डेटा पोस्ट कर सकते हैं, तो मैं यह जांचने में सक्षम हूं कि मेरा सुझाव कितना उपयोगी है।

मैं आपको उपयोगकर्ताओं के डेटा को मैट्रिक्स में बदल सकता हूं जैसे कि नामकरण के रूप में rownames और कौशल के रूप में। क्यूं कर?

  1. आप सामान्य अनुक्रमण के माध्यम से डेटा तक पहुँचने के बजाय हर जगह which(==) का उपयोग करके एक छोटे से गति सुधार हो सकती है। या कम से कम यह आपके कोड को और अधिक पठनीय बना देगा।

  2. अधिक महत्वपूर्ण बात यह है कि मैट्रिक्स के भीतर मूल्य बदलना स्मृति-वार में किया जाता है; जबकि डेटा.फ्रेम के साथ, मुझे लगता है कि आपका कोड हर बार पूरी नई वस्तु बना रहता है, जो समय लेने वाला होना चाहिए।


# read and transform your data 
data <- read.csv("data.txt", header = FALSE) 
names(data) <- c("user", "p1", "p2", "skill", "win", "looser", "time") 
users <- data.matrix(read.csv("users.txt", header = FALSE, row.names = 1)) 
colnames(users) <- paste("C", 1:6) 

for (i in 1:nrow(data)) { 
    game <- data[i,] 
    winner.old <- users[game$win, game$skill] 
    looser.old <- users[game$looser, game$skill] 
    winner.new <- winner.old + 32/2 * (1 - 0 + (1/2) * (looser.old-winner.old)/200) 
    looser.new <- looser.old + 32/2 * (0 - 1 + (1/2) * (winner.old-looser.old)/200) 
    users[game$win, game$skill] <- winner.new 
    users[game$looser, game$skill] <- looser.new 
} 

यह बहुत आसान को पढ़ने के लिए नहीं है? उम्मीद है कि यह थोड़ा तेज भी होगा, कृपया परीक्षण करें और मुझे बताएं। या एक बड़ा डेटा सेट प्रदान करें जिसके साथ हम खेल सकते हैं। धन्यवाद।

+1

पैकेज में देखता हूं पहली बार मैंने किसी को 'data.matrix' का उपयोग किया है, मैंने सोचा था कि यह कभी भी मदद फ़ाइल नहीं छोड़ी है। मैं सोच रहा था कि यह कहां उपयोगी हो सकता है। –

संबंधित मुद्दे