简体   繁体   English

凸包中点之间的最大距离

[英]Maximum distance between points in a convex hull

I am solving a problem in which I need to find the maximum distance between two points on a plane (2D) .So there is an O(n^2) approach in which I calculate distance between every point in the graph .我正在解决一个问题,我需要找到平面 (2D) 上两点之间的最大距离。所以有一个 O(n^2) 方法,我计算图中每个点之间的距离。 I also implemented a convex hull algorithm now my approach is I compute convex hull in O(nlogn) and then use the O(n^2) algorithm to compute maximum distance between points in the convex hull.我还实现了凸包算法,现在我的方法是在 O(nlogn) 中计算凸包,然后使用 O(n^2) 算法计算凸包中点之间的最大距离。 Is there a better approach than this to compute the max distance in convex hull有没有比这更好的方法来计算凸包中的最大距离

Here are my algorithm :这是我的算法:

O(n^2) O(n^2)

 def d(l1,l2):
    return ((l2[0]-l1[0])**2+(l2[1]-l1[1])**2)
def find_max_dist(L):
    max_dist = d(L[0], L[1])
    for i in range(0, len(L)-1):
        for j in range(i+1, len(L)):
            max_dist = max(d(L[i], L[j]), max_dist)
    return max_dist

convex hull凸包

def convex_hull(points):
    """Computes the convex hull of a set of 2D points.

       Input: an iterable sequence of (x, y) pairs representing the points.
       Output: a list of vertices of the convex hull in counter-clockwise order,
       starting from the vertex with the lexicographically smallest coordinates.
       Implements Andrew's monotone chain algorithm. O(n log n) complexity.
"""

      # Sort the points lexicographically (tuples are compared lexicographically).
      # Remove duplicates to detect the case we have just one unique point.
        points = sorted(set(points))

      # Boring case: no points or a single point, possibly repeated multiple times.
    if len(points) <= 1:
        return points

    # 2D cross product of OA and OB vectors, i.e. z-component of their 3D cross product.
    # Returns a positive value, if OAB makes a counter-clockwise turn,
    # negative for clockwise turn, and zero if the points are collinear.
    def cross(o, a, b):
        return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0])

    # Build lower hull
    lower = []
    for p in points:
        while len(lower) >= 2 and cross(lower[-2], lower[-1], p) <= 0:
            lower.pop()
        lower.append(p)

    # Build upper hull
    upper = []
    for p in reversed(points):
        while len(upper) >= 2 and cross(upper[-2], upper[-1], p) <= 0:
            upper.pop()
        upper.append(p)

    # Concatenation of the lower and upper hulls gives the convex hull.
    # Last point of each list is omitted because it is repeated at the beginning of the other list.
    return lower[:-1] + upper[:-1]

overall algorithm整体算法

 l=[]
 for i in xrange(int(raw_input())):   # takes input denoting number  of points in the plane
     n=tuple(int(i) for i in raw_input().split())  #takes each point and makes a tuple
     l.append(n)                                # appends to n

 if len(l)>=10:
        print find_max_dist(convex_hull(l))
 else:
        print find_max_dist(l)

Now how do I improve the running time of my approach and is there a better way to compute this ?现在我如何改进我的方法的运行时间,有没有更好的方法来计算它?

Once you have a convex hull, you can find two furthest points in linear time.一旦你有了一个凸包,你就可以在线性时间内找到两个最远的点。

The idea is to keep two pointers: one of them points to the current edge (and is always incremented by one) and the other one points to a vertex.这个想法是保持两个指针:一个指向当前边(并且总是加一),另一个指向一个顶点。

The answer is the maximum distance between end points of an edge and the vertex for all edges.答案是边的端点与所有边的顶点之间的最大距离。

It is possible to show (the proof is neither short nor trivial, so I will not post it here) that if we keep incrementing the second pointer every time after moving the first one as long as it increases the distance between the line that goes through the edge and a vertex, we will find the optimal answer.可以证明(证明既不简短也不琐碎,所以我不会在这里发布)如果我们在移动第一个指针后每次都增加第二个指针,只要它增加通过的线之间的距离边和顶点,我们将找到最佳答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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