Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 分治最近对算法_Java_Algorithm_Optimization_Divide And Conquer_Closest Points - Fatal编程技术网

Java 分治最近对算法

Java 分治最近对算法,java,algorithm,optimization,divide-and-conquer,closest-points,Java,Algorithm,Optimization,Divide And Conquer,Closest Points,我试图创建一个算法,从随机生成的点返回最近的一对。我已经完成了这个算法,但是该算法的分治法并没有比蛮力法快多少。如何优化代码,使其在(n log n)时间返回 import java.util.*; 导入java.lang.*; 导入静态java.lang.Math.min; 导入静态java.lang.StrictMath.abs; 公共级近距离空中飞行{ 专用静态随机生成器;//用于随机数 公共静态类点实现可比较的{ 公共长x,y; //建造师 公共点(长x、长y){ 这个.x=x; 这个。

我试图创建一个算法,从随机生成的点返回最近的一对。我已经完成了这个算法,但是该算法的分治法并没有比蛮力法快多少。如何优化代码,使其在(n log n)时间返回

import java.util.*;
导入java.lang.*;
导入静态java.lang.Math.min;
导入静态java.lang.StrictMath.abs;
公共级近距离空中飞行{
专用静态随机生成器;//用于随机数
公共静态类点实现可比较的{
公共长x,y;
//建造师
公共点(长x、长y){
这个.x=x;
这个。y=y;
}
公共国际比较(p点){
//将其与p进行比较,有三个结果:>0、==0或p.y)?1:-1;
}
其他的
返回(this.x>p.x)?1:-1;
}
公共字符串toString(){
返回“(“+Long.toString(this.x)+”,“+Long.toString(this.y)+”);
}
公共双倍距离(p点){
长dx=(this.x-p.x);
longdy=(this.y-p.y);
返回Math.sqrt(dx*dx+dy*dy);
}
}
公共静态点[]平面;
公共静态点[]T;
公共静态点[]Y;
公共静态int N;//平面中的点数
公共静态void main(字符串[]args){
//读迷宫大小的书
扫描仪扫描=新扫描仪(System.in);
试试{
System.out.println(“飞机上有多少个点?”);
N=scan.nextInt();
}
捕获(例外情况除外){
例如printStackTrace();
}
scan.close();
//创建N个点的平面。
平面=新点[N];
Y=新点[N];
T=新点[N];
随机生成器=新随机();
对于(int i=0;ilong x=randomGenerator.nextInt(N使用以下方法对minDisSimple进行更改。您可以获得更高的性能

static double minDisSimple() {
    // A straightforward method for computing the distance
    // of the two closest points in plane[0..N-1].

    // to be completed
    double midDis = Double.POSITIVE_INFINITY;
    double temp;
    for (int i = 0; i < N - 1; i++) {
        for (int j = i + 1; j < N; j++) {
            temp = plane[i].distance(plane[j]);
            if (temp < midDis) {
                midDis = temp;
            }
        }
    }
    return midDis;

}
static double minDisSimple(){
//一种计算距离的简单方法
//平面[0..N-1]中最近的两个点。
//待完成
双正中=双正无穷大;
双温;
对于(int i=0;i

对于少量的点,简单的方法是好的,但大量的点分治是好的。尝试10、100、1000、10000、100000、1000000的点数。

minDisDivideConquer()中的一个关键方面
是指构造辅助数组
T
的循环遍历所有
N
点。由于总共有
O(N)
递归调用,因此每次遍历所有
N
点都会导致
O(N^2)
的复杂性,相当于简单算法的复杂性

循环实际上应该只考虑在<代码>低和<代码>高< /代码>之间的索引点。此外,它可以被分成两个单独的循环,从MID(向前和向后)开始,并且在检查距离已经过大时中断。


minDisDivideConquer()
方法在“4点或更多点”情况下的另一个可能改进是防止查找递归调用中已经考虑的对

如果我的理解正确,数组
T
包含x轴上距离中点足够近的点,因此
T
中的一对点有可能生成比单个半集的距离小的距离

但是,不必查看同时位于
mid
之前或
mid
之后的点(因为在递归调用中已经考虑了这些对)

因此,可能的优化是构造两个列表
T_left
T_right
(而不是
T
),并检查点对之间的距离,以便一个位于
mid
的左侧,另一个位于右侧。
这样,我们就不用计算
|T |*(|T |-1)/2
距离,而只研究
|T | u左|*| T | |右|=| T |
。这个值最多是
(| T | T |)/2(| T | T |/2)T |距离的2倍左右(这是最坏的情况,但实际对数也可以小得多,包括零).

这不是一个代码审查网站,我投票将此问题作为离题题关闭,因为StackOverflow不是一个审查网站。你应该在上面发布你的代码。@SaschaKolberg它可以根据需要重新编写,但CR问题应该对代码的任何方面和所有方面都开放,请参见CR.Meta上的。
static double minDisSimple() {
    // A straightforward method for computing the distance
    // of the two closest points in plane[0..N-1].

    // to be completed
    double midDis = Double.POSITIVE_INFINITY;
    double temp;
    for (int i = 0; i < N - 1; i++) {
        for (int j = i + 1; j < N; j++) {
            temp = plane[i].distance(plane[j]);
            if (temp < midDis) {
                midDis = temp;
            }
        }
    }
    return midDis;

}