平面内最小点对Java代码实现

平面内最小点对算法(Closest Pair Algorithm)是一种用于寻找平面上距离最近的两个点的算法。它是计算几何和算法设计中的经典问题之一。

以下是平面内最小点对算法的详解:

  1. 输入:给定平面上的n个点的集合。

  2. 排序:首先将输入的点按照x坐标进行排序,如果有多个点具有相同的x坐标,则按照y坐标进行排序。

  3. 分治策略:使用分治法将点集划分为左右两个子集,分别记为Pleft和Pright。

  4. 递归求解

    • 递归地在Pleft和Pright中寻找最小点对。如果点集大小小于等于3,则可以直接通过暴力比较所有点对的距离来求解。
    • 分别找到Pleft和Pright中的最小点对,记为dleft和dright。
  5. 合并阶段

    • 在Pleft和Pright之间建立一个垂直于x轴的竖线,记为L。以L为界线,在距离L线距离不超过dleft的区域中,找到与L的距离小于dleft的点的集合,记为Sleft。
    • 在Sleft中,按照y坐标进行排序,并计算任意两个点之间的距离。遍历Sleft中的每一个点,对于每一个点p,只需要检查与p相邻的6个点,即p的前5个点和后一个点(总共6个点)。
    • 在Sleft中找到最小点对,记为dminleft。
  6. 输出:比较dleft和dright的大小,取其中较小的作为最小点对的初始值,然后将dminleft与这个初始值进行比较,得到最终的最小点对。

平面内最小点对算法的时间复杂度是O(n log n),其中n是输入点集的大小。该算法利用了分治法的思想,并通过剪枝策略减少了不必要的计算,从而高效地找到最小点对。

需要注意的是,该算法假设平面上的点没有重复。如果存在重复的点,则需要在合并阶段进行特殊处理。此外,还可以通过使用数据结构(如KD-Tree)来进一步优化算法的性能。

以下是使用Java语言实现平面内最小点对算法的示例代码:

import java.util.Arrays;

class Point {
    int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

class ClosestPairAlgorithm {

    public static double closestPair(Point[] points) {
        // 按照x坐标排序
        Arrays.sort(points, (p1, p2) -> p1.x - p2.x);
        return closestPairUtil(points, 0, points.length - 1);
    }

    private static double closestPairUtil(Point[] points, int left, int right) {
        if (right - left <= 3) {
            // 若点集大小小于等于3,则直接通过暴力比较距离来求解
            return bruteForce(points, left, right);
        }

        int mid = (left + right) / 2;
        Point midPoint = points[mid];

        // 递归地在左右子集中寻找最小点对的距离
        double dl = closestPairUtil(points, left, mid);
        double dr = closestPairUtil(points, mid + 1, right);

        // 取两个子集中最小点对的距离作为初始值
        double d = Math.min(dl, dr);

        // 查找距离中线距离不超过d的点的集合
        Point[] strip = new Point[right - left + 1];
        int j = 0;
        for (int i = left; i <= right; i++) {
            if (Math.abs(points[i].x - midPoint.x) < d) {
                strip[j++] = points[i];
            }
        }

        // 在strip中查找最小点对的距离
        double dStrip = stripClosest(strip, j, d);
        
        return Math.min(d, dStrip);
    }

    private static double bruteForce(Point[] points, int left, int right) {
        double minDist = Double.POSITIVE_INFINITY;
        for (int i = left; i <= right; ++i) {
            for (int j = i + 1; j <= right; ++j) {
                double dist = distance(points[i], points[j]);
                minDist = Math.min(minDist, dist);
            }
        }
        return minDist;
    }

    private static double stripClosest(Point[] strip, int size, double d) {
        double minDist = d;
        Arrays.sort(strip, 0, size, (p1, p2) -> p1.y - p2.y);

        for (int i = 0; i < size; ++i) {
            for (int j = i + 1; j < size && (strip[j].y - strip[i].y) < minDist; ++j) {
                double dist = distance(strip[i], strip[j]);
                minDist = Math.min(minDist, dist);
            }
        }
        return minDist;
    }

    private static double distance(Point p1, Point p2) {
        int dx = p1.x - p2.x;
        int dy = p1.y - p2.y;
        return Math.sqrt(dx * dx + dy * dy);
    }
}

public class Main {
    public static void main(String[] args) {
        Point[] points = { new Point(2, 3), new Point(12, 30), new Point(40, 50), new Point(5, 1),
                new Point(12, 10), new Point(3, 4) };
        double closestDist = ClosestPairAlgorithm.closestPair(points);
        System.out.println("Closest distance: " + closestDist);
    }
}

在上述代码中,我们定义了Point类来表示平面上的点。ClosestPairAlgorithm类包含了实现最小点对算法的静态方法closestPair和辅助方法。

Main类的main方法中,我们创建了一个包含6个点的数组,并使用ClosestPairAlgorithm类的closestPair方法计算最小点对的距离。最后,将结果打印输出。

这是一个简化的示例代码,用于演示最小点对算法的基本思路。在实际应用中,可能需要根据具体问题进行适当的修改和扩展。

如果你想更深入地了解人工智能的其他方面,比如机器学习、深度学习、自然语言处理等等,也可以点击这个链接,我按照如下图所示的学习路线为大家整理了100多G的学习资源,基本涵盖了人工智能学习的所有内容,包括了目前人工智能领域最新顶会论文合集和丰富详细的项目实战资料,可以帮助你入门和进阶。

链接: 人工智能交流群【最新顶会与项目实战】(点击跳转)

在这里插入图片描述

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RRRRRoyal

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值