[英]Python: How can I make this function for calculating distances faster?
我正在用 Python 和 PyGame 制作一个简单的汽车游戏,以试验神经网络,尤其是 NEAT 算法。 玩家应该驾驶汽车通过赛道,并且不得触及边界。 为了让神经网络“看到”,网络可以使用几个“传感器”来获取 position 信息。 他们以不同的程度计算到边界的距离,边界由掩码定义。
对于几辆车来说效果很好,但是当 20 辆或更多车在赛道上时,事情就会慢很多。
cProfile output 的一部分:
38382471 function calls in 52.762 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.001 0.001 52.762 52.762 <string>:1(<module>)
26435 0.158 0.000 1.086 0.000 cargame.py:113(draw)
26435 0.045 0.000 0.045 0.000 cargame.py:121(drawRadars)
26435 14.103 0.001 22.550 0.001 cargame.py:128(checkRadars)
26435 0.129 0.000 24.262 0.001 cargame.py:149(update)
26435 0.060 0.000 0.282 0.000 cargame.py:157(checkColliding)
273 0.001 0.000 0.011 0.000 cargame.py:169(drawOnMouse)
据我了解这些行,我的 checkRadars() 有点瓶颈。 每辆车都会调用它(当它们更新时,每帧都会发生这种情况)。
def checkRadars(self, mask):
xcenter, ycenter = self.rect.center
#self.radars.clear()
v = (180-180*self.blindspot)/(self.radarCount-1)
w = (90-90*self.blindspot)
# dont mind these weird calculations
for n in range(self.radarCount):
length = 1
x, y = xcenter, ycenter
rangle = v*n-w
rad = -math.radians(self.angle+rangle)
while isInBound(x, y) and not mask.get_at((x, y)) and length < 100:
length += 1
x = int(xcenter + math.sin(rad) * length)
y = int(ycenter - math.cos(rad) * length)
if length == 100:
length = length*10
我已尽我所能优化该方法,将一些计算移出循环,等等,但它仍然不够快。 降低长度不是一种选择,因为它对我的口味来说已经太低了。
好吧,我尝试以其他方式实现这个 function 并设法让它更有效率。
事实证明,计算量超出了必要的范围,并且 for range 循环比 while 循环更好。
新代码:
def checkRadars(self, mask):
xcenter, ycenter = self.rect.center
startd = -90+self.blindspot
stopd = 90-self.blindspot
dg = 180-self.blindspot*2
self.radars.clear()
for d in range(startd, stopd+1, int(dg/(self.radarCount-1))):
x, y = xcenter, ycenter
rad = math.radians(360 - (self.angle + d + 90))
xvector = math.cos(rad)
yvector = math.sin(rad)
length = 1
for length in range(1,200,5):
if(not isInBound(x, y) or mask.get_at((x,y))):
break
x = int(xcenter + xvector * length)
y = int(ycenter + yvector * length)
else: # nobreak
length = 2000
self.radars.append(((x, y),length))
新 cProfile output:
65266150 function calls in 49.991 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.002 0.002 49.991 49.991 <string>:1(<module>)
215157 0.619 0.000 4.604 0.000 cargame.py:112(draw)
215157 18.651 0.000 27.422 0.000 cargame.py:131(checkRadars)
215157 0.449 0.000 34.656 0.000 cargame.py:156(update)
checkRadars() 现在显然需要更少的时间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.