问题:
设p1=(x1, y1), p2=(x2, y2), …, pn=(xn, yn)是平面上n个点构成的集合S,设计算法找出集合S中距离最近的点对。
蛮力算法描述:
int ClosestPoints(int n, int x[ ], int y[ ]){
minDist=Double.POSITIVE_INFINITY;;
for (i=1; i< n; i++)
for (j=i+1; j<=n; j++)
{
d=(x[i]-x[j])* (x[i]-x[j])+(y[i]-y[j])* (y[i]-y[j]);
if (d< minDist) {
minDist=d;
index1=i;
index2=j;
}
}
return minDist;
}
程序:
import java.util.*;
public class ClosestPair1{
public static void main(String[] args)
{
/**
*输入需要比较的点的对数存在变量n中
*/
Scanner in=new Scanner(System.in);
System.out.println("How many pairs of points to compare?(有多少对点需要比较?)");
int n=in.nextInt();
int[] x=new int[n];
int[] y=new int[n];
/**
*输入这些点的横坐标和纵坐标分别存储在x[n]和y[n]
*/
System.out.println("Please enter these points,X-coordinate(请输入这些点,横坐标):");
for(int i=0;i< n;i++)
{
x[i]=in.nextInt();
}
System.out.println("Please enter these points,Y-coordinate(请输入这些点,纵坐标):");
for(int i=0;i< n;i++)
{
y[i]=in.nextInt();
}
double minDist=Double.POSITIVE_INFINITY;
double d;
int indexI=0;
int indexJ=0;
/**
*求解最近对距离存于minDist中
*/
double startTime=System.currentTimeMillis();//startTime
for(int i=0;i< n-1;i++)
{
for(int j=i+1;j< n;j++)
{
d=Math.sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
if(d< minDist)
{
minDist=d;
indexI=i;
indexJ=j;
}
}
}
double endTime=System.currentTimeMillis();//endTime
/**
*打印输出最后求出的结果,最近的是哪两个点,以及最近距离和程序用的时间
*/
System.out.println("The closest pair is:("+x[indexI]+","+y[indexI]+") and ("+x[indexJ]+","+y[indexJ]+")");
System.out.println("The closest distance is "+minDist);
System.out.println("Basic Statements take(基本语句用时) "+(endTime-startTime)+" milliseconds!");
}
}
运行:
分治算法 描述:
可以划一条垂线,把点集分成两半:PL和PR。于是最近点对或者在PL中,或者在PR中,或者PL,PR各有一点。
把三种距离情况定义为dL, dR, dC.
其中dL, dR可以递归求解,于是问题就变为计算dC。
设s=min(dL, dR). 通过观察能得出结论:如果dC<s,则只需计算dC。如果dC满足这样的条件,则决定dC的两点必然在分割线的s距离之内,称之为带(strip)
否则不可能满足dC<s, 于是缩小了需要考虑的点的范围。
程序:
import java.util.*;
public class ClosestPair2
{
public static void main(String[] args)
{
/**
*输入需要比较的点的对数存在变量n中
*/
Scanner in=new Scanner(System.in);
System.out.println("How many pairs of points to compare?(有多少对点需要比较?)");
int n=in.nextInt();
/**
*输入这些点的横坐标和纵坐标,存储在点数组S[n]中
*/
System.out.println("Please enter these points,X-coordinate and Y-coordinate.(请输入这些点,x坐标和y坐标):");
Point[] S=new Point[n];
double startTime=System.currentTimeMillis();//starttime
for(int i=0;i< n;i++)
{
int x=in.nextInt();
int y=in.nextInt();
S[i]=new Point(x,y);
System.out.println("("+S[i].getX()+","+S[i].getY()+")");
}
/**
*求出这点的x坐标的中位数mid
*/
int minX=(int)Double.POSITIVE_INFINITY;
int maxX=(int)Double.NEGATIVE_INFINITY;
for(int i=0;i< n;i++)
{
if(S[i].getX()< minX)
minX=S[i].getX();
if(S[i].getX()>maxX)
maxX=S[i].getX();
}
int mid=(minX+maxX)/2;
/**
*以mid为界把S中的点分为两组分别存放在范型数组列表point1和point2中
*/
ArrayList point1=new ArrayList();
ArrayList point2=new ArrayList();
for(int i=0;i< n;i++)
{
if(S[i].getX()<=mid)
point1.add(S[i]);
else
point2.add(S[i]);
}
/**
*将范型数组列表转换为数组类型S1和S2
*/
Point[] S1=new Point[point1.size()];
Point[] S2=new Point[point2.size()];
point1.toArray(S1);
point2.toArray(S2);
/**
*将S1和S2中的点按x 坐标升序排列
*/
sortX(S1);
sortX(S2);
/**
*打印输出排序后S1和S2的点
*/
System.out.print("The points in S1 are:");
for(int i=0;i< S1.length;i++)
System.out.print("("+S1[i].getX()+","+S1[i].getY()+") ");
System.out.println();
System.out.print("The points in S2 are:");
for(int i=0;i< S2.length;i++)
System.out.print("("+S2[i].getX()+","+S2[i].getY()+") ");
System.out.println();
/**
*求S1中点的最近对及其距离并打印输出结果
*/
double minDist1=Double.POSITIVE_INFINITY;
int indexI1=0;
int indexJ1=0;
for(int i=0;i< S1.length-1;i++)
{
for(int j=i+1;j< S1.length;j++)
{
double d=Math.sqrt(Math.pow((S1[i].getX()-S1[j].getX()),2)+Math.pow((S1[i].getY()-S1[j].getY()),2));
if(d< minDist1)
{
minDist1=d;
indexI1=i;
indexJ1=j;
}
}
}
System.out.println("The closest pair in S1 is: "+"("+S1[indexI1].getX()+","+S1[indexI1].getY()+")"+
"and("+S1[indexJ1].getX()+","+S1[indexJ1].getY()+")"+",and the distance is "+minDist1);
/**
*求S2中点的最近对及其距离并打印输出结果
*/
double minDist2=Double.POSITIVE_INFINITY;
int indexI2=0;
int indexJ2=0;
for(int i=0;i< S2.length-1;i++)
{
for(int j=i+1;j< S2.length;j++)
{
double d=Math.sqrt(Math.pow((S2[i].getX()-S2[j].getX()),2)+Math.pow((S2[i].getY()-S2[j].getY()),2));
if(d< minDist2)
{
minDist2=d;
indexI2=i;
indexJ2=j;
}
}
}
System.out.println("The closest pair in S2 is: "+"("+S2[indexI2].getX()+","+S2[indexI2].getY()+")"+
"and("+S2[indexJ2].getX()+","+S2[indexJ2].getY()+")"+",and the distance is "+minDist2);
double d1=Math.min(minDist1,minDist2);
/**
*在S1,S2中收集距离中线两侧小于dl的点,分别存在P1[]和P2[]中
*/
ArrayList< Point> pp1=new ArrayList< Point>();
ArrayList< Point> pp2=new ArrayList< Point>();
for(int i=0;i< S1.length;i++)
{
if((mid-S1[i].getX())< d1)
pp1.add(S1[i]);
}
for(int i=0;i< S2.length;i++)
{
if((S2[i].getX()-mid)< d1)
pp2.add(S2[i]);
}
Point[] P1=new Point[pp1.size()];
Point[] P2=new Point[pp2.size()];
pp1.toArray(P1);
pp2.toArray(P2);
/**
*将P1和P2中的点按Y坐标升序排列
*/
sortY(P1);
sortY(P2);
/**
*求解P1和P2两者之间可能的最近对距离
*/
double d2=Double.POSITIVE_INFINITY;
for(int i=0;i< P1.length;i++)
{
for(int j=0;j< P2.length;j++)
{
if(Math.abs(P1[i].getY()-P2[j].getY())< d1)
{
double temp=Math.sqrt(Math.pow((P1[i].getX()-P2[j].getX()),2)+Math.pow((P1[i].getX()-P2[j].getX()),2));
if(temp< d2)
d2=temp;
}
}
}
double endTime=System.currentTimeMillis();//endtime
/**
*打印输出最后求出的结果,最近的是哪两个点,以及最近距离和程序用的时间
*/
System.out.print("The points in P1 are:");
for(int i=0;i< P1.length;i++)
System.out.print("("+P1[i].getX()+","+P1[i].getY()+") ");
System.out.println();
System.out.print("The points in P2 are:");
for(int i=0;i< P2.length;i++)
System.out.print("("+P2[i].getX()+","+P2[i].getY()+") ");
System.out.println();
System.out.println("d2="+d2);
double minDist=Math.min(d1,d2);
System.out.println("The closest distance is "+minDist);
System.out.println("Basic Statements take(基本语句用时) "+(endTime-startTime)+" milliseconds!");
}
/**
*设计按点Point的x坐标升序排列的函数sortX
*/
public static void sortX(Point[] p)
{
for(int i=0;i< p.length-1;i++)
{
for(int j=0;j< p.length-1-i;j++)
{
if(p[j].getX()>p[j+1].getX())
{
int t=p[j].getX();
p[j].setX(p[j+1].getX());
p[j+1].setX(t);
int n=p[j].getY();
p[j].setY(p[j+1].getY());
p[j+1].setY(n);
}
}
}
}
/**
*设计按点Point的y坐标升序排列的函数sortY
*/
public static void sortY(Point[] p)
{
for(int i=0;i< p.length-1;i++)
{
for(int j=0;j< p.length-1-i;j++)
{
if(p[j].getY()>p[j+1].getY())
{
int t=p[j].getY();
p[j].setY(p[j+1].getY());
p[j+1].setY(t);
int n=p[j].getX();
p[j].setX(p[j+1].getX());
p[j+1].setX(n);
}
}
}
}
}
/**
* 建立自己的类Point
*/
class Point implements Cloneable
{
public Point()
{
x=0;
y=0;
}
public Point(int x,int y)
{
this.x=x;
this.y=y;
}
public void setX(int x)
{
this.x=x;
}
public void setY(int y)
{
this.y=y;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
private int x;
private int y;
}
http://www.java3z.com/cwbwebhome/article/article5/51197.html
分享到:
相关推荐
通过对比蛮力法与分治法求解最近对问题,我们可以看到不同算法策略对时间和空间效率的影响。蛮力法简单直接但效率低下,而分治法虽然实现复杂,但能有效处理大规模数据集,体现了算法设计中的权衡与优化。在实际应用...
算法设计实验报告,包括:分治法和蛮力法求最近对问题的基本思想、时间复杂度分析,C++实现代码,两种算法运行时间的比较,运行结果截图,实验心得。
### 最近对问题:分治法与蛮力法 #### 一、背景介绍 最近对问题(Closest Pair Problem)是指在平面上找到距离最近的两个点。这个问题在计算几何和计算机科学领域有着广泛的应用,比如地图应用中的路径规划、模式...
蛮力法、分治法和动态规划法设计最大子段和问题的算法,一、试分别利用蛮力法、分治法和动态规划法求解最大子段和问题,要求写出C/C++程序实现和算法的效率分析。程序运行结果要同时给出最大子段和的值以及由哪个子段...
下面我们将深入探讨解决这一问题的三种主要方法:蛮力法、分治法和动态规划法。 1. **蛮力法**: 蛮力法是最直观的解法,通过遍历所有可能的子序列来找出最大和。对于长度为n的数组,我们需要检查n*(n+1)/2个子...
2. **随机点集生成与算法实现**:生成不同数量的随机点集,并采用蛮力法和分治法计算这些点集的最近点对。 3. **算法效率比较**:分别统计两种方法在N=100,1000,10000,100000时的运行时间,并进行理论与实测效率的...
1. 对于平面上给定的N个点...4. 分别对N=100100010000100000,统计算法运行时间,比较理论效率与实测效率的差异,同时对蛮力法和分治法的算法效率进行分析和比较。5. 如果能将算法执行过程利用图形界面输出,可获加分。
比如,可以生成大量随机坐标,然后使用蛮力法和分治法分别寻找最近邻点对。这将有助于揭示在实际问题中的性能差异。 综上所述,蛮力法和分治法是编程中常见的两种算法思路。蛮力法简单直接但效率受限,适合小规模...
使用java编写 用分治法实现对于平面上最近点对的查找 使用Swing作为界面
**标题解析:**“分治法求最近点对”指的是使用分治策略来解决寻找二维空间中距离最近的两个点的问题。在计算机科学中,分治法是一种将复杂问题分解成更小、易于处理的部分的方法,然后分别解决这些部分,最后合并...
本实验项目的目的是了解蛮力法和分治法的根本思想,并学会运用蛮力法和分治法解决实际系统设计应用中碰到的问题。蛮力法和分治法是两种常用的算法设计方法,本实验将通过实现选择、冒泡排序、旅行商问题、背包问题等...
下面将详细讲解标题和描述中提及的八种算法设计方法:蛮力法、分治法、动态规划、贪心算法、分支限界法、回溯法、近似算法以及减制法。 1. **蛮力法(Brute Force)**: 蛮力法是最直观的解决问题的方法,通常通过...
在C语言编程中,蛮力法是初学者常用来解决问题的方式之一,因为它易于理解和实现,虽然它可能不是最优解。 在C语言中,蛮力法的实现通常涉及循环和条件判断。例如,如果题目是寻找两个整数数组中的公共元素,蛮力法...
分治法是一种常用的问题求解策略,特别是在处理复杂问题时能有效降低计算复杂度和问题规模。在空中飞行管理问题上,飞行安全是至关重要的,其中一项挑战就是预先识别出哪两架飞机之间存在最大的碰撞风险。如果能够...
本文将对蛮力法、减治法和分治法进行详细的介绍,并对其在排序算法中的应用进行分析。 一、蛮力法 蛮力法是一种简单直接解决问题的方法,它的思想是基于问题的描述和概念。蛮力法可以用于许多解决实际问题,如选择...
4. 分别对N=100,1000,10000,100000,统计算法运行时间,比较理论效率与实测效率的差异,同时对蛮力法和分治法的算法效率进行分析和比较。 5. 如果能将算法执行过程利用图形界面输出,可获加分。
分别用蛮力法、分治法、减治法实现a^n 蛮力法是一种基本的算法思想,用于解决某些问题时,它的时间复杂度较高,但它的优点是易于理解和实现。蛮力法的基本思想是通过循环来实现某些操作,例如这里的Power1函数,它...
总结起来,修正的分治法在求解最近点对问题时,通过有序划分和有效剪枝,大大降低了搜索的复杂度,尤其在大数据集上表现出较高的效率。这种方法不仅体现了分治法的思想,也展示了如何通过算法设计的创新来优化问题的...
分别用蛮力法、分治法、减治法求a的n次方,并比较运行时间
/*蛮力法 n^2 对于数组a[n],其连续的子段有 以a[0]开始的 , { a[0] }, { a[0],a[1] },{ a[0],a[1],a[2] }.....共n 个 以a[1]开始的, { a[1] }, { a[1],a[2] },{ a[1],a[2],a[3] }.....共n-1个 ... 以a[n]开始的,...