繁体   English   中英

Python:我怎样才能使这个 function 更快地计算距离?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM