📌  相关文章
📜  最小封闭圆|设置 1(1)

📅  最后修改于: 2023-12-03 15:10:36.859000             🧑  作者: Mango

最小封闭圆

最小封闭圆是指包含所有给定点的圆中,半径最小的圆。该问题在计算机科学中有广泛的应用,如计算几何、图形学和机器学习等领域。

算法

著名的 Welzl 算法可以用来解决最小封闭圆问题。

算法描述
  1. 随机选择一个点作为园的中心点。
  2. 如果圆包含所有的点,则退出递归,该圆即为最小封闭圆。
  3. 否则,随机选择一个点 p,递归包含所有点(除了 p)的最小封闭圆。
  4. 如果点 p 在这个圆内,退出递归,该圆即为最小封闭圆。
  5. 否则,使用点 p 更新圆的半径和中心点,继续递归包含所有点(除了 p)的最小封闭圆。
代码实现

下面是一个 Python 实现的 Welzl 算法:

from random import shuffle

def dist(p, q):
    return (p[0] - q[0])**2 + (p[1] - q[1])**2

def welzl(points, boundary=[]):
    if len(boundary) == 3:
        return circle(*boundary)
    elif not points:
        return circle(*boundary)
    else:
        p = points.pop()
        c = welzl(points, boundary)
        if c.contains(p):
            return c
        boundary.append(p)
        return welzl(points, boundary)
        
class circle:
    def __init__(self, *args):
        if len(args) == 2:
            self.center = complex(*args)
            self.radius = 0
        elif len(args) == 3:
            self.center = circle.center(*args)
            self.radius = abs(args[0] - self.center)
            
    def contains(self, p):
        return abs(p - self.center) <= self.radius + 1e-10
    
    @staticmethod
    def from_diameter(p, q):
        return circle((p+q)/2, abs(p-q)/2)
    
    @staticmethod
    def center(p, q, r):
        a = p - r
        b = q - r
        c = p - q
        d = abs(c**2 * b - c*b**2)
        return ((a*abs(b)**2 + b*abs(a)**2 + c*d)/(2*abs(c)**2)).real + r.real + \
               (((a*abs(b)**2 + b*abs(a)**2 + c*d)/(2*abs(c)**2)).imag + r.imag)*1j
    
    def __repr__(self):
        return f"circle({round(self.center.real, 2)}, {round(self.center.imag, 2)}, {round(self.radius, 2)})"
性能分析

Welzl 算法的时间复杂度为 O(n),其中 n 是给定点的数量。

参考资料