【问题标题】:How can I improve this code with nested loops?如何使用嵌套循环改进此代码?
【发布时间】:2015-10-09 21:03:15
【问题描述】:

我有一个函数可以计算每帧中两点之间的碰撞次数。 我不知道如何改进这个非常慢的代码。

     #data example
     #[[89, 814, -77.1699249744415, 373.870468139648, 0.0], [71, 814, -119.887828826904, 340.433287620544, 0.0]...]

    def is_collide(data, req_dist):
        #req_dist - minimum distance when collision will be count

        temp = data 

        temp.sort(key=Measurements.sort_by_frame)
        max_frame = data[-1][1]
        min_frame = data[0][1]
        collissions = 0

        # max_frame-min_frame approximately 60000
        # the slowest part
        for i in range(min_frame, max_frame):
            frames = [line for line in temp if line[1] == i]
            temp = [line for line in temp if line[1] != i]
            l = len(frames)

            for j in range(0, l, 1):
                for k in range(j+1, l, 1):
                    dist = ((frames[j][2] - frames[k][2])**2 + (frames[j][3]-frames[k][3])**2)**0.5
                    if dist < req_dist:
                        collissions += 1

        return collissions

【问题讨论】:

  • 它没有错误,你只想提高性能吗?
  • 您能否提供一个包含简短数据示例、预期输入和输出的最小可验证示例?
  • 当你 temp.sort() 仅供参考时,你正在改变数据
  • code review 可能是一个更合适的地方问
  • req_dist 的值是多少?

标签: python loops


【解决方案1】:

计算每对点之间的距离很昂贵:O(n**2) 操作。一般来说,即使对于小的 n,这也可能非常昂贵。

我建议退后一步,看看是否有更好的数据结构来做到这一点::

  1. 四叉树:查看关于四叉树的维基百科文章。这些可能用于碰撞检测。 https://en.wikipedia.org/wiki/Quadtree
  2. 在 Jon Bentley 的《Programming Pearls》一书中,第 2 节第 5 列与此非常相关。他描述了在 N 体问题中计算类似问题所需的所有优化。我强烈建议您阅读这篇文章以获得一些想法。

话虽如此,我认为在某些地方您可以进行一些相当简单的改进并获得适度的加速。

1) 使用求幂(实际上是平方根)的距离计算是一项昂贵的操作。
2) 您使用 n**2 来计算平方,而将 n 自身相乘可能会更快。

您可以将其替换为 temp(并自行相乘),但更好的是:您不需要它!只要所有距离的计算方式相同(没有 **.5),您就可以比较它们。换句话说,只要您只需要相对值,就可以在没有 sqrt 操作的情况下比较距离。我在这里回答了一个类似的问题:

Fastest way to calculate Euclidean distance in c

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多