2017-06-06 51 views
3

我有一個算法,我在python中實現。該算法可能會執行1.000.000次,所以我想盡可能優化它。算法中的基數是三個列表(energy,pointvalList)以及兩個計數器pe向量化或優化一個循環,其中每次迭代都取決於前一次迭代的狀態

這兩個列表energypoint包含0和1之間的數字,我基於此決定。 p是一個點計數器和e是一個能量計數器。我可以交易點能源,每個能源的成本定義在valList(這是時間相關)。我也可以換一種方式。但我必須馬上交易。

該算法的概要:

  1. 優惠布爾列表,其中在energy元件在閾值之上並且在point元素低於另一閾值。這是一個交易能量積分的決定。獲取點的相應列表,該列表決定交易點的能量
  2. 在每個布爾列表中。刪除所有真值後的另一個真正的價值(如果我已經交易所有點的能量,我不允許再做點)
  3. 對於每個項目對(pB,點布爾和eB,能源布爾)從兩個布爾列表:如果PB是真實的,我有點,我想交易我所有的點爲能。如果eB是真的,並且我有能量,我想把我所有的能量換成積分。

這是我想出了實施:

start = time.time() 
import numpy as np 

np.random.seed(2) #Seed for deterministic result, just for debugging 

topLimit = 0.55 
bottomLimit = 0.45 

#Generate three random arrays, will not be random in the real world 
res = np.random.rand(500,3) #Will probably not be much longer than 500 
energy = res[:,0]   
point = res[:,1] 
valList = res[:,2] 

#Step 1: 
#Generate two bools that (for ex. energy) is true when energy is above a threashold 
#and point below another threshold). The opposite applies to point 
energyListBool = ((energy > topLimit) & (point < bottomLimit)) 
pointListBool = ((point > topLimit) & (energy < bottomLimit)) 

#Step 2: 
#Remove all 'true' that comes after another true since this is not valid 
energyListBool[1:] &= energyListBool[1:]^energyListBool[:-1] 
pointListBool[1:] &= pointListBool[1:]^pointListBool[:-1] 

p = 100 
e = 0 

#Step 3: 
#Loop through the lists, if point is true, I loose all p but gain p/valList[i] for e 
#If energy is true I loose all e but gain valList[i]*e for p 
for i in range(len(energyListBool)): 
    if pointListBool[i] and e == 0: 
     e = p/valList[i] #Trade all points to energy 
     p = 0 
    elif energyListBool[i] and p == 0: 
     p = valList[i]*e #Trade all enery to points 
     e = 0 

print('p = {0} (correct for seed 2: 3.1108006690739174)'.format(p)) 
print('e = {0} (correct for seed 2: 0)'.format(e)) 

end = time.time() 
print(end - start) 

我所用struggeling是如何(如果這是可以做到),以矢量化的循環,這樣我就可以使用而不是我腦海中可能會更快的for-loop。

回答

1

在當前的問題設置中,由於向量化本質上要求您的n計算步驟不應該依賴於以前的n-1步驟,所以這是不可能的。然而,有時可能找到所謂的「封閉形式」的重複f(n) = F(f(n-1), f(n-2), ... f(n-k)),即找到不依賴於n的明確表達式f(n),但這是一個單獨的研究問題。此外,從算法的角度來看,這樣的矢量化不會給很多,因爲算法的複雜性仍然是C*n = O(n)。然而,由於「複雜性常數」在實踐中確實很重要,因此有不同的方法來減少它。例如,在C/C++中重寫你的關鍵循環不應該是一個大問題。