Dijkstra算法和Floyed算法「建议收藏」

Dijkstra算法和Floyed算法「建议收藏」Dijkstra算法和Floyed算法最短路径:在非网图中,最短路径是指两顶点之间经历的边数最少的路径。在网图中,最短路径是指两顶点之间经历的边上权值之和最短的路径。最短路径问题:单源点到其他顶点的最短路径:Dijkstra方法,O(n2)按路径长度递增任意一对顶点之间的最短路径:Floyed方法,O(n3)Dijkstra算法:按路径长度递增1.设置一个集合S存放已经找到最短…

大家好,又见面了,我是你们的朋友全栈君。

Dijkstra算法和Floyed算法

最短路径:

非网图中,最短路径是指两顶点之间经历的边数最少的路径。
网图中,最短路径是指两顶点之间经历的边上权值之和最短的路径。

最短路径问题:

单源点到其他顶点的最短路径:
Dijkstra方法,O(n2)按路径长度递增
任意一对顶点之间的最短路径:
Floyed方法,O(n3)

Dijkstra算法:按路径长度递增

1.设置一个集合S存放已经找到最短路径的顶点,S的初始状态只包含源点v,
2.对vi∈V-S,假设从源点v到vi的有向边为最短路径(从v到其余顶点的最短路径的初值)。
3.以后每求得一条最短路径v, …, vk,就将vk加入集合S中,并将路径v, …, vk , vi与原来的假设相比较,取路径长度较小者为最短路径。
4.重复上述过程,直到集合V中全部顶点加入到集合S中。

路径长度最短的最短路径(即第一条最短路)的特点:
在这条路径上,必定只含一条边,并且这条边上的权值最小。

下一条路径长度次短的最短路径的特点:
(1)直接从源点到该点(只含一条边);
(2)从源点经过顶点v1(第一条最短路径所依附的顶点),再到达该顶点(由两条边组成)。

再下一条路径长度次短的最短路径的特点:
(1)直接从源点到该点(只含一条边);
(2)从源点经过顶点v1,再到达该顶点(由两条边组成);
(3)从源点经过顶点v2,再到达该顶点(两条条边);
(4)从源点经过顶点v1、v2,再到达该顶点(多条边)。

其余最短路径的特点:
(1)直接从源点到该点(只含一条边);
(2)从源点经过已求得最短路径的顶点(集合S中的顶点),再到达该顶点。

迪杰斯特拉算法的主要步骤:

(1) g为用邻接矩阵表示的带权图。
S←{v0} , dist[i]= g.arcs[v0][vi],path[i]=“v0vi”或“”;
将v0到其余顶点的路径长度初始化为权值;
(2) 选择vk,使得
dist[vk]=min(dist[i] | vi∈V-S)
vk为目前求得的下一条从v0出发的最短路径的终点。
将vk加入到S中
(3) 修改从v0出发到集合V-S上任一顶点vi的最短路径的长度。如果
dist[k]+ g.arcs[k][i]<dist[i]
则将dist[i]修改为
dist[k]+ g.arcs[k][i]
path[i]=path[k]+”vi”
(4) 重复(2)、(3) n-1次,即可按最短路径长度的递增顺序,逐个求出v0到图中其它每个顶点的最短路径。

const int MAX=1000;
void  Dijkstra(MGraph g, int v){
       for ( i =0; i<g.vexnum ; i++){
	 dist[i]=g.arcs[v][i];  
               if ( dist[i]!= MAX) 
                      path [i]=g.vertex[v]+g.vertex[i];
               else
                      path[i]=“”;
       }
       S[0]=g.vertex[v]; 
       num=1;  
       While (num<g.vextexNum){
    k=0;
    for(i=0;i<G.vertexNum;i++)
           if((dist[i]<dist[k])   k=i
    cout<<dist[k]<<path[k];
    s[num++]=G.vertex[k];                
    for(i=0;i<G.vertexNum;i++)
             if(dist[k]+g.arc[k][i]<dist[i] {
		 dist[i]=dist[k]+g.arc[k][i];
                       path[i]=path[k]+g.vertex[i];
               }
}
}

Floyed算法——基本思想:

设图g用邻接矩阵法表示, 求图g中任意一对顶点vi、 vj间的最短路径。
(-1) 将vi到vj 的最短的路径长度初始化为(vi,vj), 然后进行如下n次比较和修正:
(0) 在vi、vj间加入顶点v0,比较(vi, v0, vj)和(vi, vj)的路径的长度,取其中较短的路径作为vi到vj的且中间顶点号不大于0的最短路径。
(1) 在vi、vj间加入顶点v1,
得(vi, …,v1)和(v1, …,vj),其中:
(vi, …, v1)是vi到v1 的且中间顶点号不大于0的最短路径,
(v1, …, vj) 是v1到vj 的且中间顶点号不大于0的最短路径,
这两条路径在上一步中已求出。
将(vi, …, v1, …, vj)与上一步已求出的且vi到vj 中间顶点号不大于0的最短路径比较,取其中较短的路径作为vi到vj 的且中间顶点号不大于1的最短路径。
(2)在vi、vj间加入顶点v2,得
(vi, …, v2)和(v2, …, vj), 其中:
(vi, …, v2)是vi到v2 的且中间顶点号不大于1的最短路径,
(v2, …, vj) 是v2到vj 的且中间顶点号不大于1的最短路径,
这两条路径在上一步中已求出。
将(vi, …, v2, …, vj)与上一步已求出的且vi到vj 中间顶点号不大于1的最短路径比较, 取其中较短的路径作为vi到vj 的且中间顶点号不大于2的最短路径。

void Floyd(MGraph G)
{
  for (i=0; i<G.vertexNum; i++)        
     for (j=0; j<G.vertexNum; j++)
     {
        dist[i][j]=G.arc[i][j];
        if (dist[i][j]!=∞) 
             path[i][j]=G.vertex[i]+G.vertex[j];
        else path[i][j]=""; 
     }
          for (k=0; k<G.vertexNum; k++)         
      for (i=0; i<G.vertexNum; i++)       
         for (j=0; j<G.vertexNum; j++)
             if (dist[i][k]+dist[k][j]<dist[i][j]) {
                  dist[i][j]=dist[i][k]+dist[k][j];
                  path[i][j]=path[i][k]+path[k][j];
            }
}

完整代码(Dijkstra):

/*输入:
5 6
0
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1 
或 
6 9
0
0 1 1
0 2 12
1 2 9
1 3 3
2 4 5
3 2 4
3 4 13
3 5 15
4 5 4
*/
#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;
 
#define N 520
int edge[N][N],weight[N],disp[N];
 
bool visited[N] = {false};
const int inf = 999999;
 
int main(){
	int prev[N];//用来标注当前结点的上一个结点,以便输出两点间最短路线 
	
	fill(edge[0],edge[0] + N * N,inf);//注意这里要是N*N,要不然不是全部 
	fill(disp,disp + N,inf);
	
	
	int n,m;//对应城市数,城市之间连线数
	cin>>n>>m;
	
	int start_point;
	cin>>start_point;//输入起点城市 
	
	int a,b,c;
	for(int i=0;i < m;i++)
	{
		cin>>a>>b>>c;
		edge[a][b] = edge[b][a] = c; 	
	}
	
	for(int i=0;i<N;i++){
		prev[i] = i;//初始状态设每个点的前驱为自身
		edge[i][i] = 0;
	}
		
	
	disp[start_point] = 0;
	for(int i = 0;i < n;i++){
		int u = -1,min = inf;
		for(int j = 0;j < n;j++){
			if(visited[j] == false && disp[j] <= min)
			{
				u = j;
				min = disp[j];
			}
		}	
		
		if(u == -1)
			break;
		
		visited[u] = true;
		for(int v = 0;v < n;v++){
			if(visited[v] == false && edge[u][v] != inf)
			{
				if(disp[u] + edge[u][v] < disp[v]){
					disp[v] = disp[u] + edge[u][v];
					prev[v] = u;//prev保存当前结点的上一个节点,以便输出最短路线
					cout<<v<<" "<<prev[v]<<endl; 
				} 		
			}
		}		
	}
	
	//显示起点到各个点的最短路径	
	for (int i=0;i<n;i++)
	{
		cout<<"起点"<<start_point<<"到"<<i<<"的最短距离为: "<<disp[i]<<endl;
	}
	
	//显示起到到某个点的线路 
	int end_point;//终点
	cout<<"请输入终点:"; 
	cin>>end_point; 
	stack<int> myStack;
	
	int temp = end_point;
	myStack.push(end_point);//先加终点 
	while(start_point != temp){
		temp = prev[temp];
		myStack.push(temp);//注意这里是把当前点的上一个结点放进去,此时换成了temp 
	}
	
	cout<<"起点"<<start_point<<"到"<<end_point<<"的最短路线为: ";
	while(!myStack.empty()){
		cout<<myStack.top()<<" ";
		myStack.pop(); 
	}
	
	return 0;
}

完整代码(Floyed):

#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
const int MaxSize=100;
 
class  MGraph
{
public:
    MGraph(char a[],int n,int e);
    ~MGraph(){}
    friend void Floyd(MGraph G);
private:
    char   vertex[MaxSize];             //节点数组
    int  arc[MaxSize][MaxSize];      //矩阵
    int vertexNum,arcNum;            //节点数与边数
    int visited[MaxSize];            //访问记录
};
 
MGraph::MGraph(char a[],int n,int e)
{
    int i,j,k;
    vertexNum=n;
    arcNum=e;
    for(i=0;i<vertexNum;i++)
    {
        vertex[i]=a[i];
    }
 
    for(i=0;i<vertexNum;i++)
        for(j=0;j<vertexNum;j++)
    {
        arc[i][j]=0;
    }
 
    for(int p=0;p<arcNum;p++)
    {
        std::cout<<"输入第"<<p+1<<"条边及权值:"<<std::endl;
        std::cin>>i>>j>>k;
        arc[i][j]=k;
    }
 
}
 
void Floyd(MGraph G)
{
    int i,j,k;
    int dist[MaxSize][MaxSize]={0};
    for(i=0;i<G.vertexNum;i++)                 //初始化最短路径数组,使两点间路径初始为直接权值
        for(j=0;j<G.vertexNum;j++)
    {
        dist[i][j]=G.arc[i][j];
    }
    for(k=0;k<G.vertexNum;k++)
        for(j=0;j<G.vertexNum;j++)
            for(i=0;i<G.vertexNum;i++)
                if((dist[i][k]+dist[k][j]<dist[i][j]&&dist[i][k]!=0&&dist[k][j]!=0&&dist[i][j]!=0)||dist[i][j]==0)
    {
        dist[i][j]=dist[i][k]+dist[k][j];
    }
    for(i=0;i<G.vertexNum;i++)
        for(j=0;j<G.vertexNum;j++)
            if(i!=j)
        {
            std::cout<<G.vertex[i]<<"到"<<G.vertex[j]<<"的最短路径为:"<<dist[i][j]<<std::endl;
        }
}
int main()
{
 
    int e,n;
    std::cout<<"点的个数:"<<"  ";
    std::cin>>e;
 
    std::cout<<"边的个数:"<<"  ";
    std::cin>>n;
 
    char  s[e];
    for(int i=0;i<e;i++)
    {
        std::cout<<"输入第"<<i+1<<"个点:";
        std::cin>>s[i];
    }
    MGraph m(s,e,n);
    Floyd(m);
    return 0;
}

一起加油!学好数据结构和算法!!!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/148627.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • stl文件格式特点_常见文件格式

    stl文件格式特点_常见文件格式一、介绍STL文件格式(stereolithography,光固化立体造型术的缩写)是由3DSYSTEMS公司于1988年制定的一个接口协议,是一种为快速原型制造技术服务的三维图形文件格式。S

  • 互联网研发部门组织架构_百度组织架构图2019

    互联网研发部门组织架构_百度组织架构图2019互联网业务研发架构体系指南(草稿V0.0.1)大纲业务技术 稳定性 【稳定性day0】稳定性治理的三种思想—亚马逊、Netflix与蚂蚁金服 【稳定性day1】从DBA到运维架构总监之路-专注的力量 【稳定性day2】当当网的高可用之道 【稳定性day3】蘑菇街的运维体系-如何撑住双十一 【稳定性day4】美团外卖高可用的演进之路-日活两千万的…

    2022年10月12日
  • 全局平均池化(global-average-pooling)

    全局平均池化在很多视觉任务中会用到。之前对darknet-53结构分析的时候,特别留意了一下全局平局池化。其实,这个操作就是它的字面意思:把特征图全局平均一下输出一个值,也就是把W*H*D的一个张量变成1*1*D的张量。下列引用来自stackoverflow:WithGlobalpoolingreducesthedimensionalityfrom3Dto1D.The…

  • dom.querySelector和document.getElementById区别

    dom.querySelector和document.getElementById区别、document.getElementById可以查询纯数字的iddom.querySelectordocument.querySelectorAll(’[id=“111”]’)在某个dom下寻找相应选择器的元素背景产品反馈项目系统模板复制之后,元素无法拖拽。经排查发现元素继承自move组件。而每个元素绑定的id竟然纯数字;复制模板之后由于项目的复杂性无法统一的对复制出…

  • 音频解码SBC_立体声音频编解码芯片

    音频解码SBC_立体声音频编解码芯片SBC音频编解码算法浅析1.SBC算法简介SBC是subbandcode的缩写,也可称为子带编码在A2DP协议中,SBC算法是默认支持的蓝牙SBC算法是一种以中等比特率传递高质量音频数据的低计算复杂度的音频编码算法1.1算法基本框图SBC系统使用一个余弦调制的滤波器组,用来解析和同步。滤波器组可设定成4或8个子带子带信号的量化采用比特分配器和自适应脉冲编码器组调制可用的比特位数

  • Google搜索引擎的发展历程「建议收藏」

    Google搜索引擎的发展历程「建议收藏」+

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号