簡體   English   中英

如何有效地找到一組點的邊界框?

[英]How to efficiently find the bounding box of a collection of points?

我有幾個點存儲在一個數組中。 我需要找到那些點的界限,即。 限定所有點的矩形。 我知道如何用普通的Python解決這個問題。

我想知道有沒有比天真的最大,最小的數組或內置方法更好的方法來解決問題。

points = [[1, 3], [2, 4], [4, 1], [3, 3], [1, 6]]
b = bounds(points) # the function I am looking for
# now b = [[1, 1], [4, 6]]

我獲得性能的方法是盡可能將事情降低到C級:

def bounding_box(points):
    x_coordinates, y_coordinates = zip(*points)

    return [(min(x_coordinates), min(y_coordinates)), (max(x_coordinates), max(y_coordinates))]

通過我的(粗略)測量,它比@ ReblochonMasque的bounding_box_naive()運行快約1.5倍。 而且顯然更優雅。 ;-)

你不能比O(n)做得更好,因為你必須遍歷所有的點來確定xymaxmin

但是,您可以減少常數因子,並且只遍歷列表一次; 然而,目前還不清楚這是否會給你一個更好的執行時間,如果確實如此,那將是大量積分。

[編輯]:事實上它沒有,“天真”的方法是最有效的。

這是“天真”的方法:(這是兩者中最快的)

def bounding_box_naive(points):
    """returns a list containing the bottom left and the top right 
    points in the sequence
    Here, we use min and max four times over the collection of points
    """
    bot_left_x = min(point[0] for point in points)
    bot_left_y = min(point[1] for point in points)
    top_right_x = max(point[0] for point in points)
    top_right_y = max(point[1] for point in points)

    return [(bot_left_x, bot_left_y), (top_right_x, top_right_y)]

和(也許?)不太天真:

def bounding_box(points):
    """returns a list containing the bottom left and the top right 
    points in the sequence
    Here, we traverse the collection of points only once, 
    to find the min and max for x and y
    """
    bot_left_x, bot_left_y = float('inf'), float('inf')
    top_right_x, top_right_y = float('-inf'), float('-inf')
    for x, y in points:
        bot_left_x = min(bot_left_x, x)
        bot_left_y = min(bot_left_y, y)
        top_right_x = max(top_right_x, x)
        top_right_y = max(top_right_y, y)

    return [(bot_left_x, bot_left_y), (top_right_x, top_right_y)]

分析結果:

import random
points = [(random.randrange(-1000, 1000), random.randrange(-1000, 1000))  for _ in range(1000000)]

%timeit bounding_box_naive(points)
%timeit bounding_box(points)

尺寸= 1,000點

1000 loops, best of 3: 573 µs per loop
1000 loops, best of 3: 1.46 ms per loop

大小= 10,000點

100 loops, best of 3: 5.7 ms per loop
100 loops, best of 3: 14.7 ms per loop

大小100,000點

10 loops, best of 3: 66.8 ms per loop
10 loops, best of 3: 141 ms per loop

大小1,000,000點

1 loop, best of 3: 664 ms per loop
1 loop, best of 3: 1.47 s per loop

顯然,第一個“不太天真”的方法更快2.5 - 3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM