算法导论求n个点的最小距离

合集下载

最短距离算法范文

最短距离算法范文

最短距离算法范文最短路径算法被广泛应用于许多领域,例如路由算法、导航系统、网络优化等。

本文将介绍三种常见的最短距离算法:Dijkstra算法、贝尔曼-福特算法和弗洛伊德算法。

1. Dijkstra算法:Dijkstra算法是一种基于贪心的算法,用于解决单源最短路径问题。

在一个有向加权图中,该算法从源节点开始,逐步选择与源节点距离最短的节点,直到到达目标节点。

具体步骤如下:1)创建一个距离列表,记录源节点到每个节点的距离,初始状态为无限大。

2)将源节点的距离设置为0,并标记为已访问。

3)从源节点开始,遍历与当前节点相邻的节点,并更新距离列表中的距离。

4)选择一个当前距离最小的节点,标记为已访问。

5)重复步骤3和步骤4,直到目标节点被标记为已访问或没有节点可访问。

2.贝尔曼-福特算法:贝尔曼-福特算法是一种解决任意两个节点之间最短路径的算法。

该算法通过多次迭代,逐步更新节点之间的距离,直到收敛到最短路径为止。

具体步骤如下:1)创建一个距离列表,记录源节点到每个节点的初始距离,初始状态为无限大。

2)将源节点的距离设置为0。

3)重复以下步骤N-1次(N为图中节点的个数):a)遍历图中的每条边,如果当前边的权重与源节点到边的起点的距离之和小于边的终点的距离,则更新边终点的距离。

4)遍历图中的每条边,如果存在一条边满足上述条件,则图中存在负权重环,算法无法得出最短路径。

5)如果没有负权重环,则距离列表即为最短路径。

3.弗洛伊德算法:弗洛伊德算法是一种解决任意两个节点之间最短路径的算法。

该算法通过多次迭代,逐步更新节点之间的距离,直到收敛到最短路径为止。

与贝尔曼-福特算法不同的是,弗洛伊德算法可以处理含有负权重边的图。

具体步骤如下:1)创建一个邻接矩阵,用于记录每对节点之间的初始距离。

2)通过多次迭代,根据节点之间的中间节点更新距离矩阵。

3)重复以下步骤N次(N为图中节点的个数):a)遍历图中的每对节点,如果当前节点之间的距离大于通过一些中间节点的距离之和,则更新距离矩阵中的距离。

计算两点之间的最短距离

计算两点之间的最短距离

计算两点之间的最短距离题⽬链接:题⽬⼤意:给定N个点的坐标,找出距离最短的两个点的序号.如果最短距离相同,输出序号最⼩的⼀组.题⽬要求输出三种不同计算⽅式下的最短距离序号:欧⼏⾥得距离:Math.sqrt(|x2-x1|2+|y2-y1|2)曼哈顿距离:|x2-x1|+|y2-y1|棋盘距离:Math.max(|x2-x1|,|y2-y1|)因为N的个数是5000个,可以直接双重循环取得最⼩距离. 单纯的理解⼀下三种距离.Accept代码:import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.List;import java.util.StringTokenizer;public class source {public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));StringTokenizer st = new StringTokenizer(br.readLine());int N = Integer.parseInt(st.nextToken());int[][] points = new int[N+1][2];for(int i = 1;i<=N;i++){st = new StringTokenizer(br.readLine());points[i] = new int[]{Integer.parseInt(st.nextToken()),Integer.parseInt(st.nextToken())};}List<int[]> result = getEuclidPosition(points);for(int[] ans:result){System.out.println(ans[0]+" "+ans[1]);}}private static List<int[]> getEuclidPosition(int[][] points){double minEuclidDistance = Integer.MAX_VALUE;int[] euclidPosition = new int[2];double minCityDistance = Integer.MAX_VALUE;int[] cityPosition = new int[2];double minChessDistance = Integer.MAX_VALUE;int[] chessPosition = new int[2];CalcMinPoint calcMinPointEuclid;CalcMinPoint calcMinPointCity;CalcMinPoint calcMinPointChess;for(int i = 1;i<points.length;i++){for(int j = 1;j<points.length;j++){if(i == j){continue;}double euclidDistance = getEuclidDistance(points[i],points[j]);double cityDistance = getCityDistance(points[i],points[j]);double chessDistance = getChessDistance(points[i],points[j]);calcMinPointEuclid = new CalcMinPoint(minEuclidDistance, euclidPosition, i, j, euclidDistance).invoke(); minEuclidDistance = calcMinPointEuclid.getMinEuclidDistance();euclidPosition = calcMinPointEuclid.getEuclidPosition();calcMinPointCity = new CalcMinPoint(minCityDistance, cityPosition, i, j, cityDistance).invoke(); minCityDistance = calcMinPointCity.getMinEuclidDistance();cityPosition = calcMinPointCity.getEuclidPosition();calcMinPointChess = new CalcMinPoint(minChessDistance, chessPosition, i, j, chessDistance).invoke(); minChessDistance = calcMinPointChess.getMinEuclidDistance();chessPosition = calcMinPointChess.getEuclidPosition();}}List<int[]> result = new ArrayList<int[]>();result.add(euclidPosition);result.add(cityPosition);result.add(chessPosition);return result;}private static double getChessDistance(int[] point, int[] point1) {return Math.max(Math.abs(point[0]-point1[0]),Math.abs(point[1]-point1[1]));}private static double getCityDistance(int[] point, int[] point1) {return Math.abs(point[0]-point1[0])+Math.abs(point[1]-point1[1]);}private static double getEuclidDistance(int[] p1, int[] p2){return Math.pow(p1[0]-p2[0],2)+Math.pow(p1[1]-p2[1],2);}private static class CalcMinPoint {private double minEuclidDistance;private int[] euclidPosition;private int i;private int j;private double euclidDistance;public CalcMinPoint(double minEuclidDistance, int[] euclidPosition, int i, int j, double euclidDistance) { this.minEuclidDistance = minEuclidDistance;this.euclidPosition = euclidPosition;this.i = i;this.j = j;this.euclidDistance = euclidDistance;}public double getMinEuclidDistance() {return minEuclidDistance;}public int[] getEuclidPosition() {return euclidPosition;}public CalcMinPoint invoke() {if(minEuclidDistance > euclidDistance){minEuclidDistance = euclidDistance;if(i < j){euclidPosition = new int[]{i,j};}else{euclidPosition = new int[]{j,i};}}else if(minEuclidDistance == euclidDistance){int position0 = -1;int position1 = -1;if(i<j){ position0 = i; position1 = j; } else{ position0 = j; position1 = i; } if(euclidPosition[0]>position0){ euclidPosition = new int[]{position0,position1};}else if(euclidPosition[0] == position0 && euclidPosition[1]>position1){euclidPosition = new int[]{position0,position1};}}return this;}}}。

平面n个点的最短连线算法

平面n个点的最短连线算法

平面n个点的最短连线算法
平面n个点的最短连线算法是一个经典的计算几何问题,通常被称为旅行商问题(Traveling Salesman Problem, TSP)。

这个问题要求找到一条路径,使得一个旅行商从给定的n个城市(在平面上表示为点)出发,访问每个城市恰好一次,然后返回起始城市,且所走的总距离最短。

解决TSP问题有多种算法,包括暴力搜索、动态规划、遗传算法、模拟退火等。

然而,对于大规模问题(即n很大时),这些算法往往难以在合理时间内找到最优解,因为TSP 是一个NP-hard问题,即没有已知的多项式时间复杂度的算法能够解决所有规模的TSP问题。

在实际应用中,通常使用启发式算法来寻找近似最优解。

这些算法虽然不能保证找到最优解,但可以在较短的时间内找到一个相对较好的解。

一种常用的启发式算法是最近邻算法(Nearest Neighbor Algorithm),它从一个点开始,每次选择离当前点最近的未访问过的点作为下一个访问点,直到所有点都被访问过为止。

另一种常用的启发式算法是遗传算法(Genetic Algorithm),它模拟生物进化过程中的自然选择和遗传机制,通过不断迭代搜索空间来寻找近似最优解。

遗传算法通常能够找到比最近邻算法更好的解,但也需要更长的计算时间。

总之,平面n个点的最短连线问题是一个NP-hard问题,没有已知的多项式时间复杂度的算法能够解决所有规模的问题。

在实际应用中,通常使用启发式算法来寻找近似最优解。

最短路径算法

最短路径算法

§distance[j]=distance[u]+G[u][j]; §path[j]=u; §}}}
2、算法的正确性和计算复杂性
(1)贪心选择性质 (2)最优子结构性质 (3)计算复杂性 对于具有n个顶点和e条边的带权有向图,如果用 带权邻接矩阵表示这个图,那么Dijkstra算法的主循 环体需要 O (n)时间。这个循环需要执行n-1次,所以完 O(时间。算法的其余部分所需要时间不 n2 ) 成循环需要 O(n 2 ) 超过 。
7.5所有点对的最短路径问题
§对于一个各边权值均大于0的有n个顶点的带 权有向图G=(V,E),求所有顶点之间的最短 路径和最短距离。
图的邻接矩阵表示法
1
1 1
3
0 2
9
2
2
8 9 6
V = 2
3
L= 8 0 6
1 ∞ 0
(b )
(a )
复习Dijkstra算法
其基本思想是,设置顶点集合S并不断地作 基本思想是 设置顶点集合S 贪心选择来扩充这个集合 一个顶点属于集合S 来扩充这个集合。 贪心选择来扩充这个集合。一个顶点属于集合S 当且仅当从源到该顶点的最短路径长度已知。 当且仅当从源到该顶点的最短路径长度已知。 初始时, 中仅含有源点。 初始时,S中仅含有源点。设u是G的某一个 顶点,把从源点到u且中间只经过S 顶点,把从源点到u且中间只经过S中顶点的路称 为从源到u的特殊路径,并用数组dist distance记录 为从源到u的特殊路径,并用数组dist 记录 当前每个顶点所对应的最短特殊路径长度。 当前每个顶点所对应的最短特殊路径长度。 Dijkstra算法每次从 算法每次从V Dijkstra算法每次从V-S中取出具有最短特殊路 长度的顶点u 添加到S 长度的顶点u,将u添加到S中,同时对数组 distance作必要的修改。一旦S包含了所有V中 作必要的修改。 dist 作必要的修改 一旦S包含了所有V 顶点,distance就记录了从源到所有其它顶点 顶点,dist 就记录了从源到所有其它顶点 之间的最短路径长度。 之间的最短路径长度。

算法导论求n个点的最小距离

算法导论求n个点的最小距离
#define E_N 10 //10条边
#define BEGIN 1 //从BEGIN起点
#define END 6 //访问的有END个终点
int graph_matrix[V_N+1][V_N+1]; //下标从1开始,图数组
int distance[V_N+1]; //下标从1开始,路径长度
{
mem_p1=a[i+1];
mem_p2=a[i+2];
delta=t;
}
t=dist(a[i],a[i+2]);
if(t<delta)
{
mem_p1=a[i];
mem_p2=a[i+2];
delta=t;
}
return;
}
k=(i+j)/2;
double middle=a[k].x;//中线点
rec_cl_pair(a,i,k);//求左边点的最小距离
算法导论求n个点的最小距离
在中文算法导论649页算法:
0:把所有的点按照横坐标排序
1:用一条竖直的线L将所有的点分成两等份
2:递归算出左半部门的这段两点距离d1,右半部门的这段两点距离d2,取d=min(d1,d2)
3:算出"1个在左半部分,另外1个在右半部分"这样的点对的最短距离d3
4:结果=min(d1,d2,d3)
6>根据起点k,在graph_matrix中找出起点为k的值并用distance记录,即graph_matrix[k][i],i为循环量。
7>将当前原始点k到k的最短路径长度赋为0,goal[k]=1即已选择过。
重点算法:
1>找出与k为起点的所有终点的最短路径short_distance及终点值short_vertex(顶点);条件是与之指向的终点还没选择过。

10个节点最短路径算法题

10个节点最短路径算法题

10个节点最短路径算法题最短路径算法是图论中的一种重要算法,用于计算两个节点之间的最短路径。

在以下内容中,将介绍并讨论10个与最短路径算法相关的题目,并给出相关参考内容,以加深对该算法的理解。

1. Dijkstra算法题目:给定一个加权有向图和一个源节点,请找出从源节点到每个其他节点的最短路径。

参考内容:《算法导论》(Introduction to Algorithms)一书中第24章,提供了关于Dijkstra算法原理和实现的详细解释。

2. Bellman-Ford算法题目:给定一个加权有向图和一个源节点,请找出从源节点到每个其他节点的最短路径,其中图中可能存在负权边。

参考内容:《算法导论》第24章,提供了Bellman-Ford算法的详细解释和实现。

3. Floyd-Warshall算法题目:给定一个有向图,请找出任意两个节点之间的最短路径。

参考内容:《算法导论》第25章,提供了Floyd-Warshall算法的详细解释和实现。

4. A*算法题目:给定一个加权有向图、一个源节点和一个目标节点,请找出从源节点到目标节点的最短路径。

参考内容:《人工智能:一种现代方法》(ArtificialIntelligence: A Modern Approach)一书中第3章,提供了A*算法的详细解释和实现。

5. Johnson算法题目:给定一个加权有向图,请找出任意两个节点之间的最短路径,其中图中可能存在负权边。

参考内容:《算法导论》第25章,提供了Johnson算法的详细解释和实现。

6. SPFA算法题目:给定一个加权有向图和一个源节点,请找出从源节点到每个其他节点的最短路径。

参考内容:各种算法教材、博客文章和论文中提供了SPFA算法的详细解释和实现,如《算法导论》第24章。

7. Yen's算法题目:给定一个加权有向图、一个源节点和一个目标节点,请找出从源节点到目标节点的K条最短路径。

参考内容:论文《Finding the K Shortest Loopless Paths in a Network》中提供了Yen's算法的详细解释和实现。

最短路径算法

最短路径算法

算法的思想 (2)算法的描述 (2)算法的举例 (2)A*算法 (2)原理简介 (2)详细内容 (2)A*算法误区 (17)A*算法总结(Summary of the A* Method) (17)F LOYD算法 (17)定义 (17)核心思路 (18)算法过程 (18)优缺点分析 (18)J OHNSON算法 (23)Johnson算法要求 (23)Johnson算法结构要求 (23)Johnson算法数据结构 (23)Johnson算法的内容 (23)Johnson算法源程序 (23)D IJKSTRA算法 (27)算法简介 (27)算法描述 (27)复杂度分析 (27)算法实现 (28)测试样例 (30)算法应用的实例 (34)算法的思想设图中有n个结点,设置一个集会u,存放已经求出最短路径的结点(初始时u中的元素是源点),v-u是尚未确定最短路径的顶点的集合。

每次从v-u集合中找这样一个结点best_j:best_j是u集合中结点的邻接点,到源点的距离最短(等于到父结点的距离加上父结点到源点的距离)。

然后把该best_j置入u集合中,直到u=v。

算法的描述最短路经计算分静态最短路计算和动态最短路计算。

静态路径最短路径算法是外界环境不变,计算最短路径。

主要有Dijkstra算法,A*算法。

动态路径最短路是外界环境不断发生变化,即不能计算预测的情况下计算最短路。

典型的有D*算法。

算法的举例A*算法原理简介A*(A-Star)算法是一种静态路网中求解最短路最有效的方法。

公式表示为:f(n)=g(n)+h(n),其中f(n) 是节点n从初始点到目标点的估价函数,g(n) 是在状态空间中从初始节点到n节点的实际代价,h(n)是从n到目标节点最佳路径的估计代价。

保证找到最短路径(最优解的)条件,关键在于估价函数h(n)的选取:估价值h(n)<= n到目标节点的距离实际值,这种情况下,搜索的点数多,搜索范围大,效率低。

最小距离问题1

最小距离问题1

rec[0].x=s[low].x;rec[0].y=s[low].y; rec[1].x=s[high].x;rec[1].y=s[high].y; return Distance(s[low],s[high]); } if(high-low==2){ //三个点的情况
d1=Distance(s[low],s[low+1]); d2=Distance(s[low+1],s[high]); d3=Distance(s[low],s[high]); if((d1<d2)&&(d1<d3)){ rec[0].x=s[low].x;rec[0].y=s[low].y; rec[1].x=s[low+1].x;rec[1].y=s[low+1].y; return d1; } else if(d2<d3){ rec[0].x=s[low+1].x;rec[0].y=s[low+1].y; rec[1].x=s[high].x;rec[1].y=s[high].y; return d2; } else { rec[0].x=s[low].x;rec[0].y=s[low].y; rec[1].x=s[high].x;rec[1].y=s[high].y; return d3; }
} mid=(low+high)/2; //其他情况递归
d1=closestPoint(s,low,mid,rec); temp1[0]=rec[0]; temp1[1]=rec[1]; d2=closestPoint(s,mid+1,high,rec); temp2[0]=rec[0]; temp2[1]=rec[1]; if(d1<d2){ d=d1; rec[0]=temp1[0]; rec[1]=temp1[1]; } else { d=d2; rec[0]=temp2[0]; rec[1]=temp2[1]; } index=0; for(i=mid;(i>=low)&&((s[mid].x-s[i].x)<d);i--) P[index++]=s[i]; for(i=mid+1;(i<=high)&&((s[i].x-s[mid].x)<d);i++) P[index++]=s[i]; sort(P,P+index,cmp); for(i=0;i<index;i++){ for(j=j+1;j<index;i++){ if((P[j].y-P[i].y)>=d) break; else { d3=Distance(P[i],P[j]); //升序排列 //点集合 p2 //点集合 p1
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

算法导论求n个点的最小距离
2010-01-20 17:23
在中文算法导论649页
算法:
0:把所有的点按照横坐标排序
1:用一条竖直的线L将所有的点分成两等份
2:递归算出左半部分的最近两点距离d1,右半部分的最近两点距离d2,取
d=min(d1,d2)
3:算出“一个在左半部分,另一个在右半部分”这样的点对的最短距离d3。

4:结果=min(d1,d2,d3)
关键就是这第3步。

貌似这需要n^2的时间,把左边每个点和右边每个点都对比一下。

其实不然。

秘密就在这里。

首先,两边的点,与分割线L的距离超过d的,都可以扔掉了。

其次,即使两个点P1,P2(不妨令P1在左边,P2在右边)与分割线L的距离(水平距离)都小于d,如果它们的纵坐标之差大于d,也没戏。

就是这两点使得搜索范围大大减小:
对于左半部分的,与L的距离在d之内的,每个P1来说:右半部分内,符合以上两个条件的点P2最多只有6个!
原因就是:
d是两个半平面各自内,任意两点的最小距离,因此在同一个半平面内,任何两点距离都不可能超过d。

我们又要求P1和P2的水平距离不能超过d,垂直距离也不能超过d,在这个d*2d 的小方块内,最多只能放下6个距离不小于d的点。

因此,第3步总的比较距离的次数不超过n*6。

第3步的具体做法是:
3.1 删除所有到L的距离大于d的点。

O(n)
3.2 把右半平面的点按照纵坐标y排序。

O(nlogn)
3.3 对于左半平面内的每个点P1,找出右半平面内纵坐标与P1的纵坐标的差在d以内的点P2,计算距离取最小值,算出d3。

O(n*6) = O(n)
因为3.2的排序需要O(nlogn),
所以整个算法的复杂度就是O(n((logn)^2))。

改进:
我们对3.2这个排序的O(nlogn)不太满意。

既然整个算法是递归的,我们可以利用第2步的子递归中已经排好序的序列,在第3.2部归并这两个子列,这样3.2的复杂度变成了O(n)。

这样,整个算法就是O(nlogn)的。

代码如下: VC6.0下编译通过
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 10000
typedefstruct point{
intx,y;
}POINT;
double delta = MAX ;
inttotalnum;
POINT mem_p1,mem_p2;
int cmx(const void *a,const void *b) //比较x坐标
{
return ((POINT *)a)->x-((POINT *)b)->x;
}
intcmy(const void *a,const void *b) //比较y坐标
{
return ((POINT *)a)->y-((POINT *)b)->y;
}
double min(double p1,double p2)
{
return p1>p2?p2:p1;
}
double dist(POINT s1,POINT s2) //求两点的距离
{
double dx = s1.x-s2.x;
double dy = s1.y-s2.y;
return sqrt(dx*dx + dy*dy);
}
void rec_cl_pair(POINT a[],inti,int j)
{
double temp,xx;
int k;
if(j-i<3)//小于或等于三个点的时候可以直接求得最小距离
{
qsort(a+i,j-i+1,sizeof(a[0]),cmy);//按Y坐标从小到大排列 xx = dist(a[i],a[i+1]);//两个点的距离
if(j-i==1)//只有两个点的时候直接返回
{
if(xx<delta)
{
mem_p1 = a[i];
mem_p2 = a[i+1];
delta = xx;
}
return;
}
double t = dist(a[i+1],a[i+2]); //有三个点的情况
if(t<delta)
{
mem_p1 = a[i+1];
mem_p2 = a[i+2];
delta = t;
}
t = dist(a[i],a[i+2]);
if(t<delta)
{
mem_p1 = a[i];
mem_p2 = a[i+2];
delta = t;
}
return;
}
k=(i+j)/2;
double middle=a[k].x;//中线点
rec_cl_pair(a,i,k);//求左边点的最小距离
rec_cl_pair(a,k+1,j);//求右边点的最小距离
int t=0;
POINT v[100];
for(k=i;k<=j;k++)
{
if(a[k].x>middle-delta && a[k].x < middle+ delta)
{
t++;
v[t] = a[k];//存入离中线距离小于delta的点
}
} //t-1为剩余点的个数
qsort(v+1,t,sizeof(v[1]),cmy);//以Y坐标的大小进行排序
for(k=1;k<t;k++)
{
for(int s=k+1;s<min(double(t),double(k+7));s++)
{
temp = dist(v[k],v[s]);
if(temp<delta)
{
delta = temp;
mem_p1=v[k];
mem_p2 = v[s];
}
}
}
}
void close_pair(POINT a[])
{
int n = totalnum;
qsort(a+1,n,sizeof(a[1]),cmx);//a接收的是a+1地址,按X坐标从小到大排列
rec_cl_pair(a,1,n);
}
void main(intargc, char *argv[])
{
POINT *a;
scanf("%d",&totalnum); //输入点的总数
a = (POINT *)malloc(sizeof(point)*(totalnum+1));//多申请一个内存空间a[0]不用
for(int i=1;i<=totalnum;i++)
scanf("%d%d",&a[i].x,&a[i].y);//输入点的X和Y坐标
close_pair(a);
printf("最近点对的距离为:%.3f\n",delta);//地址从a+1开始
printf("最短距离的两个点
为:\n(%d,%d)\n(%d,%d)\n",mem_p1.x,mem_p1.y,mem_p2.x,mem_p2.y);
}。

相关文档
最新文档