1. 程式人生 > >經典演算法之Dijkstra演算法(求圖中任意一對頂點間的最短路徑)

經典演算法之Dijkstra演算法(求圖中任意一對頂點間的最短路徑)

/************************
author's email:[email protected]
date:2018.1.30
************************/
/*
迪傑斯特拉演算法思想:
	設有兩個頂點集合S和T,集合S中存放圖中已找到最短路徑的頂點,集合T存放圖中剩餘頂點,初始狀態時
	集合S中只包含源點v0,然後不斷從集合T中選取到頂點v0路徑長度最短的頂點Vu併入到集合S中。集合S
	每併入一個新的頂點Vu,都要修改頂點V0到集合T中頂點的最短路徑長度值。不斷重複此過程,直到集合T
	的頂點全部併入到S中為止。
迪傑斯特拉演算法時間複雜度分析:
	由演算法程式碼可知,本演算法主要部分為一個雙重迴圈,外層迴圈內部有兩個並列的單層迴圈,可以在取一個
	迴圈內的操作作為基本操作,基本操作執行的總次數即為雙重迴圈執行的次數,為n^2次,因此本演算法的
	時間複雜度為O(n^2)。
*/
#include<iostream>
#define INF 100//INF為比圖中任何權值都大的數
#define maxSize 7   //圖的頂點數
#define number 12   //圖的邊數
using namespace std;
typedef struct {//圖的定義
	int edges[maxSize][maxSize];//鄰接矩陣的定義
	int n, e;   //分別為頂點數和邊數
}MGraph;
MGraph createGraph(MGraph g);
void Dijkstra(MGraph g, int v, int dist[], int path[]);/*迪傑斯特拉演算法程式碼,函式結束時
dist[]存放了v點到其餘各頂點的最短路徑長度,path[]中儲存從V到各頂點的最短路徑*/
void printfPath(int path[], int a);//輸出起始點v到終點a之間的最短路徑
int main() {

	MGraph g;//定義並初始化圖g
	g.edges[maxSize][maxSize] = { 0 };
	g.n = maxSize; g.e = number;
	g = createGraph(g);//建立一個圖

	int dist[maxSize] = {0};
	int path[maxSize] = {0};
	int v = 0;//起始點
	Dijkstra(g, v, dist, path);

	cout << "頂點"<<v<<"到各頂點的最短路徑及最短路徑長度為:" << endl;
	for (int i = 1; i < maxSize; ++i)
	{
		printfPath(path, i);
		cout<<"最短路徑長度為:" << dist[i]<<endl;
	}
	system("pause");
	return 0;
}

MGraph createGraph(MGraph g) {
	int i, j;
	for (i = 0; i < maxSize; i++)
	{
		for (j = 0; j < maxSize; j++)
		{
			g.edges[i][j] = INF;
		}
	}
	g.edges[0][1] = 4;
	g.edges[1][0] = 4;
	g.edges[0][2] = 6;
	g.edges[2][0] = 6;
	g.edges[0][3] = 6;
	g.edges[3][0] = 6;
	g.edges[1][2] = 1;
	g.edges[2][1] = 1;
	g.edges[1][4] = 7;
	g.edges[4][1] = 7;
	g.edges[2][3] = 2;
	g.edges[3][2] = 2;
	g.edges[2][4] = 6;
	g.edges[4][2] = 6;
	g.edges[2][5] = 4;
	g.edges[5][2] = 4;
	g.edges[3][5] = 5;
	g.edges[5][3] = 5;
	g.edges[4][5] = 1;
	g.edges[5][4] = 1;
	g.edges[4][6] = 6;
	g.edges[6][4] = 6;
	g.edges[6][5] = 8;
	g.edges[5][6] = 8;
	g.n = maxSize;
	g.e = number;
	return g;
}

/*迪傑斯特拉演算法程式碼,函式結束時
dist[]存放了v點到其餘各頂點的最短路徑長度,path[]中儲存從V到各頂點的最短路徑*/
void Dijkstra(MGraph g, int v, int dist[], int path[])
{
	int set[maxSize];/*set[]為標記陣列,set[Vi]=0表示Vi在T中,即沒有被併入最短路徑;
					 set[Vi]=1表示Vi在S中,即已經被併入最短路徑。*/
	int min, i, j, u;

	//對各陣列初始化
	for (i = 0; i < g.n; ++i)
	{
		dist[i] = g.edges[v][i];
		set[i] = 0;
		if (g.edges[v][i] < INF)
			path[i] = v;
		else
			path[i] = -1;
	}
	set[v] = 1; path[v] = -1;//初始化結束

	for (i = 0; i < g.n - 1; ++i)
	{
		min = INF;

		/*這個迴圈每次從剩餘頂點中選出一個頂點,通往這個頂點的路徑在通往所有剩餘頂點的路徑中
		是長度最短的*/
		for (j=0;j<g.n;++j)
		{
			if (set[j] == 0 && dist[j] < min)
			{
				u = j;
				min = dist[j];
			}
		}
		set[u] = 1;//將選出的頂點併入最短路徑中

		/*這個迴圈以剛併入的頂點作為中間點,對所有通往剩餘頂點的路徑進行檢測*/
		for (j = 0; j < g.n; ++j)
		{
			/*這個if語句判斷頂點u的加入是否會出現通往頂點j的更短的路徑,如果出現,則
			改變原來路徑及其長度,否則什麼都不做。*/
			if (set[j] == 0 && dist[u] + g.edges[u][j] < dist[j])
			{
				dist[j] = dist[u] + g.edges[u][j];
				path[j] = u;

			}
		}

	}
}
void printfPath(int path[], int a)//輸出起始點v到終點a之間的最短路徑
{
	int stack[maxSize], top = -1;//定義並初始化棧
	/*這個迴圈以由葉子節點到根節點的順序將其入棧*/
	while (path[a] != -1)
	{
		stack[++top] = a;
		a = path[a];
	}
	stack[++top] = a;
	while (top != -1)
	{
		cout << stack[top--] << " ";//出棧並打印出棧元素,實現了頂點的逆序列印
	}
	cout << endl;

}

相關推薦

經典演算法Dijkstra演算法任意一對頂點路徑

/************************ author's email:[email protected] date:2018.1.30 ************************/ /* 迪傑斯特拉演算法思想: 設有兩個頂點集合S和T,集合S中

經典演算法Floyd演算法任意一對頂點路徑

/************************ author's email:[email protected] date:2018.1.30 *********************

Dijkstra演算法一個節點到其他所有節點的路徑

Dijkstra(迪傑斯特拉)演算法是典型的單源最短路徑演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。Dijkstra演算法是很有代表性的最短路徑演算法,在很多專業課程中都作為基本內容有詳細的介紹,如資料

演算法---每對頂點路徑

3.2、額外空間儲存2*(n*n)def floyd_warshall(W): import copy #需要兩個n*n矩陣的額外儲存 D_in = copy.deepcopy(W) D_ret = copy.deepcopy(W) k = 0 while k

無向Dijkstra演算法任意一對頂點路徑迪傑斯特拉演算法

public class Main{ public static int dijkstra(int[][] w1,int start,int end) { boolean[] isLable = new boolean[w1[0].length];//是否標上所有的號 i

路徑演算法Dijkstra演算法——C++實現並優化

Dijkstra演算法是一種比較經典的求圖中最短路徑演算法,它是一種貪心演算法,可以求出從源節點到圖中其他所有節點的最短路徑。適用範圍:用於求有向或無向加權圖中兩點間的最短路徑,其中邊的權值不能為負。 最近重新學習了該演算法,並用C++將其實現,同時對程式碼進行了優化,優化

演算法學習——貪心演算法刪數字小值

演算法描述 在給定的n位數字,刪除其中的k位數字( k < n),使得最後的n-k為數字為最小值(原次序不變) 演算法思路 考慮到是要移出數字,我們使用連結串列設計此演算法較為方便,連結串列可以直接移出某個位置的元素 使用貪心演算法,每一步都要達到最優 從最高位開始,若下一位比上一位要小,則將上一

一個例子讓你明白一個演算法-Dijkstra源點到各頂點路徑

演算法思想 1.在一個圖中,把所有頂點分為兩個集合P,Q(P為最短路徑集合,Q為待選集合),用dis陣列儲存源點到各個頂點的最短路徑(到自身為0)。 2.初始化P集合,就是加入源點到該集合,並在ma

的鄰接矩陣表示與路徑演算法 Dijkstra 程式碼實現

#include <stdio.h> #define MAX_VERTEX_NUM 20 //最大頂點個數 typedef int VRTYPE, InfoType; typedef enum {DG, DN, UDG, UD

Dijkstra [迪傑斯特拉]演算法思路單點到其他每個點的各個路徑Floyd演算法任意兩點短距離

先給出一個無向圖 用Dijkstra演算法(迪傑斯特拉演算法)找出以A為起點的單源最短路徑步驟如下 應用Dijkstra演算法計算從源頂點1到其它頂點間最短路徑的過程列在下表中。 Dijkstra演算法的迭代過程: Floyd演算法思想: 1、從任意一條單邊路徑開

無向路徑求解演算法——Dijkstra演算法【轉】

在準備ACM比賽的過程中,研究了圖論中一些演算法。首先研究的便是最短路的問題。《離散數學》第四版(清華大學出版社)一書中講解的Dijkstra演算法是我首先研究的源材料。       如何求圖中V0到V5的最短路徑呢?         java實現的方式如下:   

路徑演算法Dijkstra演算法鄰接矩陣實現

如題,很簡單的最短路徑,除了要利用map先將字串轉成數字,注意可能出發地目的地相同!!!! Description 經過錦囊相助,海東集團終於度過了危機,從此,HDU的發展就一直順風順水,到了2

圖解-迪傑斯特拉演算法路徑Dijkstra's Algorithm (finding shortestpaths)

轉自:http://www.mathcs.emory.edu/~cheung/Courses/171/Syllabus/11-Graph/dijkstra2.html   一. 圖解迪傑斯特拉   Before showing you the&nb

淺談路徑規劃演算法Dijkstra演算法

 迪傑斯特拉(dijkstra)演算法是典型的用來解決最短路徑的演算法,也是很多教程中的範例,由荷蘭電腦科學家狄克斯特拉於1959年提出,用來求得從起始點到其他所有點最短路徑。該演算法採用了貪心的思想,每次都查詢與該點距離最的點,也因為這樣,它不能用來解決存在負權邊的圖。解

Floyd演算法Dijkstra演算法路徑

#include <iostream> #include <cstdio> #include <vector> using namespace std; int Dis[101]; bool mark[101]; struct E { int next; i

的基本演算法單源路徑

在許多路由問題中,尋找圖中一個頂點到另一個頂點的最短路徑或最小帶權路徑是非常重要的提煉過程。正式表述為,給定一個帶權有向圖G = (V, E) , 頂點s到v中頂點t的最短路徑為在邊集E中連線s到t代價

FLoyd演算法路徑

【程式】#include <stdio.h> #define N 105 void Floyd(int D[][N],int n)//Floyd演算法  { int i,j,k; pri

路徑演算法Dijkstra演算法_Java實現

public class Graph { /* * 頂點 */ private List<Vertex> vertexs; /* * 邊 */ private int[][] edges; /* * 沒

路徑——迪傑斯坷垃演算法有向、單源路徑

最短路徑的演算法有兩種:迪傑斯坷垃演算法和弗洛伊德演算法。 但是兩種演算法各有優劣: 迪傑斯坷垃演算法適合單源點最短路徑的獲取, 弗洛伊德演算法適合各點間最短路徑的獲取,即多源點最短路徑的獲取; 今天主要講解迪傑斯坷垃演算法。 一、演算法步驟: 1、獲取鄰接矩陣,確定起始點

Dijkstra演算法單元點路徑

Dijkstra演算法解決圖中某特定點到其他點的最短路徑。 迪傑斯塔拉(Dijkstra)演算法思想: 按路徑長度遞增的次序產生最短路徑的演算法。設集合S存放已經找到最短路徑的頂點,V為所有節點的集合,S的初始狀態只包含源點V0,對Vi∈V-S。 假設從源點V0到Vi的有向