2017-06-06 54 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++中重写你的关键循环不应该是一个大问题。