Dijkstra(迪傑斯特拉)算法是典型的最短路徑路由算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴展,直到擴展到終點為止。
其基本思想是,設置頂點集合S並不斷地作貪心選擇來擴充這個集合。一個頂點屬於集合S當且僅當從源到該頂點的最短路徑長度已知。
初始時,S中僅含有源。設u是G的某一個頂點,把從源到u且中間只經過S中頂點的路稱為從源到u的特殊路徑,並用數組dist記錄當前每個頂點所對應的最短特殊路徑長度。Dijkstra算法每次從V-S中取出具有最短特殊路長度的頂點u,將u添加到S中,同時對數組dist作必要的修改。一旦S包含了所有V中頂點,dist就記錄了從源到所有其它頂點之間的最短路徑長度。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConAppDijkstra
{
class Program
{
private const int MaxSize = 6;
private const int INF = 32767; // INF表示∞
private const int MAXV = 4; // 最大頂點個數
// 結構體的成員定義里不能直接賦值,也就是等號后的應該移除,在你后面實例化整個結構體以后,
// 再對Study_Data[n].input=new double[50] 其他成員類似。順便說下其實用class簡單得多。
struct VertexType
{
public string VexNo; // 頂點編號
public string VexName; // 頂點名稱
public string otherInfo; // 頂點其他信息
} ; // 頂點類型
struct MGraph // 圖的定義
{
public int[,] edges; // 鄰接矩陣
public int n, e; // 頂點數,弧數
public VertexType[] vexs; // 存放頂點信息
} ; // 圖的鄰接矩陣類型
static void Ppath( int[] path, int i, int v) // 前向遞歸查找路徑上的頂點
{
int k;
k = path[i];
if (k == v) return; // 找到了起點則返回
Ppath(path, k, v); // 找頂點k的前一個頂點v
Console.Write( " {0}, ", k); // 輸出路徑上的終點
// Ppath(path, k, j); // 找頂點k的前一個頂點j
}
static void Ppath(MGraph g, int[] path, int i, int v) // 前向遞歸查找路徑上的頂點
{
int k;
k = path[i];
if (k == v) return; // 找到了起點則返回
Ppath(path, k, v); // 找頂點k的前一個頂點v
Console.Write( " {0}, ", g.vexs[k].VexName); // 輸出路徑上的終點
// Ppath(path, k, j); // 找頂點k的前一個頂點j
}
static void Dispath( int[] dist, int[] path, int[] s, int n, int v)
{
int i;
for (i = 0; i < n; i++)
{
if (s[i] == 1)
{
Console.Write( " 從{0}到{1}的最短路徑長度為:{2}\t路徑為: ", v, i, dist[i]);
Console.Write( " {0}, ", v); // 輸出路徑上的起點
Ppath(path, i, v); // 輸出路徑上的中間點
Console.WriteLine( " {0} ", i); // 輸出路徑上的終點
}
else
Console.WriteLine( " 從{0}到{1}不存在路徑\n ", v, i);
}
}
static void PutBothpath(MGraph g, int[] dist, int[] path, int[] s, int n, int v, int m)
{
int i;
for (i = 0; i < n; i++)
{
if (s[i] == 1)
{
// Console.Write(" 從{0}到{1}的最短路徑長度為:{2}\t路徑為:", v, i, dist[i]);
// Console.Write("{0},", v); // 輸出路徑上的起點
// Ppath(path, i, v); // 輸出路徑上的中間點
// Console.WriteLine("{0}", i); // 輸出路徑上的終點
if (i == m && dist[i] < INF)
{
Console.Write( " 從{0}到{1}的最短路徑長度為:{2}\t路徑為: ", g.vexs[v].VexName, g.vexs[i].VexName, dist[i]);
Console.Write( " {0}, ", g.vexs[v].VexName); // 輸出路徑上的起點
// Ppath(path, i, v); // 輸出路徑上的中間點
Ppath(g, path, i, v);
Console.WriteLine( " {0} ", g.vexs[i].VexName); // 輸出路徑上的終點
}
}
else
Console.WriteLine( " 從{0}到{1}不存在路徑\n ", v, i);
}
}
static void Dijkstra(MGraph g, int v)
{
int[] dist = new int[MAXV]; // 從原點v到其他的各定點當前的最短路徑長度
int[] path = new int[MAXV]; // path[i]表示從原點到定點i之間最短路徑的前驅節點
int[] s = new int[MAXV]; // 選定的頂點的集合
int mindis, i, j, u;
u = 0;
for (i = 0; i < g.n; i++)
{
dist[i] = g.edges[v, i]; // 距離初始化
s[i] = 0; // s[]置空 0表示i不在s集合中
if (g.edges[v, i] < INF) // 路徑初始化
path[i] = v;
else
path[i] = - 1;
}
s[v] = 1; // 源點編號v放入s中
path[v] = 0;
for (i = 0; i < g.n; i++) // 循環直到所有頂點的最短路徑都求出
{
mindis = INF; // mindis置最小長度初值
for (j = 0; j < g.n; j++) // 選取不在s中且具有最小距離的頂點u
if (s[j] == 0 && dist[j] < mindis)
{
u = j;
mindis = dist[j];
}
s[u] = 1; // 頂點u加入s中
for (j = 0; j < g.n; j++) // 修改不在s中的頂點的距離
if (s[j] == 0)
if (g.edges[u, j] < INF && dist[u] + g.edges[u, j] < dist[j])
{
dist[j] = dist[u] + g.edges[u, j];
path[j] = u;
}
}
Dispath(dist, path, s, g.n, v); // 輸出最短路徑
// PutBothpath(g, dist, path, s, g.n, v, 3);
}
static void initdata()
{
int i, j;
MGraph g;
g.n = 4; g.e = 8;
g.edges = new int[MAXV, MAXV];
g.vexs = new VertexType[MAXV];
// int [,] anArray = new int [2, 4] {{1,2,3,4},{5,6,7,8}};
int[,] a = new int[MAXV, MAXV] {
{ 0, 5,INF, 7},
{INF, 0, 4, 2},
{ 3, 3, 0, 2},
{INF,INF, 1, 0}
};
for (i = 0; i < g.n; i++) // 建立圖的圖的鄰接矩陣
{
for (j = 0; j < g.n; j++)
{
g.edges[i, j] = a[i, j]; ///////////////////////////////////////////// //
}
}
Console.WriteLine( " 各頂點的最短路徑: ");
}
static void initialVexInfo(MGraph g)
{
g.vexs[ 0].VexNo = " 0361 ";
g.vexs[ 0].VexName = " 西安 ";
g.vexs[ 1].VexNo = " 010 ";
g.vexs[ 1].VexName = " 北京 ";
g.vexs[ 2].VexNo = " 0681 ";
g.vexs[ 2].VexName = " 武漢 ";
g.vexs[ 3].VexNo = " 0571 ";
g.vexs[ 3].VexName = " 杭州 ";
}
static void Main( string[] args)
{
int i, j;
MGraph g;
g.n = 4; g.e = 8;
g.edges = new int[MAXV, MAXV];
g.vexs = new VertexType[MAXV];
initialVexInfo(g);
// int [,] anArray = new int [2, 4] {{1,2,3,4},{5,6,7,8}};
int[,] a = new int[MAXV, MAXV] {
{ 0, 5,INF, 7},
{ 5, 0, 4, 1},
{INF, 4, 0,INF},
{ 7, 1,INF, 0}
};
for (i = 0; i < g.n; i++) // 建立圖的圖的鄰接矩陣
{
for (j = 0; j < g.n; j++)
{
g.edges[i, j] = a[i, j];
}
}
Console.WriteLine( " 最小生成樹構成: ");
Dijkstra(g, 0);
Console.ReadKey();
}
}
}
using System.Linq;
using System.Text;
namespace ConAppDijkstra
{
class Program
{
private const int MaxSize = 6;
private const int INF = 32767; // INF表示∞
private const int MAXV = 4; // 最大頂點個數
// 結構體的成員定義里不能直接賦值,也就是等號后的應該移除,在你后面實例化整個結構體以后,
// 再對Study_Data[n].input=new double[50] 其他成員類似。順便說下其實用class簡單得多。
struct VertexType
{
public string VexNo; // 頂點編號
public string VexName; // 頂點名稱
public string otherInfo; // 頂點其他信息
} ; // 頂點類型
struct MGraph // 圖的定義
{
public int[,] edges; // 鄰接矩陣
public int n, e; // 頂點數,弧數
public VertexType[] vexs; // 存放頂點信息
} ; // 圖的鄰接矩陣類型
static void Ppath( int[] path, int i, int v) // 前向遞歸查找路徑上的頂點
{
int k;
k = path[i];
if (k == v) return; // 找到了起點則返回
Ppath(path, k, v); // 找頂點k的前一個頂點v
Console.Write( " {0}, ", k); // 輸出路徑上的終點
// Ppath(path, k, j); // 找頂點k的前一個頂點j
}
static void Ppath(MGraph g, int[] path, int i, int v) // 前向遞歸查找路徑上的頂點
{
int k;
k = path[i];
if (k == v) return; // 找到了起點則返回
Ppath(path, k, v); // 找頂點k的前一個頂點v
Console.Write( " {0}, ", g.vexs[k].VexName); // 輸出路徑上的終點
// Ppath(path, k, j); // 找頂點k的前一個頂點j
}
static void Dispath( int[] dist, int[] path, int[] s, int n, int v)
{
int i;
for (i = 0; i < n; i++)
{
if (s[i] == 1)
{
Console.Write( " 從{0}到{1}的最短路徑長度為:{2}\t路徑為: ", v, i, dist[i]);
Console.Write( " {0}, ", v); // 輸出路徑上的起點
Ppath(path, i, v); // 輸出路徑上的中間點
Console.WriteLine( " {0} ", i); // 輸出路徑上的終點
}
else
Console.WriteLine( " 從{0}到{1}不存在路徑\n ", v, i);
}
}
static void PutBothpath(MGraph g, int[] dist, int[] path, int[] s, int n, int v, int m)
{
int i;
for (i = 0; i < n; i++)
{
if (s[i] == 1)
{
// Console.Write(" 從{0}到{1}的最短路徑長度為:{2}\t路徑為:", v, i, dist[i]);
// Console.Write("{0},", v); // 輸出路徑上的起點
// Ppath(path, i, v); // 輸出路徑上的中間點
// Console.WriteLine("{0}", i); // 輸出路徑上的終點
if (i == m && dist[i] < INF)
{
Console.Write( " 從{0}到{1}的最短路徑長度為:{2}\t路徑為: ", g.vexs[v].VexName, g.vexs[i].VexName, dist[i]);
Console.Write( " {0}, ", g.vexs[v].VexName); // 輸出路徑上的起點
// Ppath(path, i, v); // 輸出路徑上的中間點
Ppath(g, path, i, v);
Console.WriteLine( " {0} ", g.vexs[i].VexName); // 輸出路徑上的終點
}
}
else
Console.WriteLine( " 從{0}到{1}不存在路徑\n ", v, i);
}
}
static void Dijkstra(MGraph g, int v)
{
int[] dist = new int[MAXV]; // 從原點v到其他的各定點當前的最短路徑長度
int[] path = new int[MAXV]; // path[i]表示從原點到定點i之間最短路徑的前驅節點
int[] s = new int[MAXV]; // 選定的頂點的集合
int mindis, i, j, u;
u = 0;
for (i = 0; i < g.n; i++)
{
dist[i] = g.edges[v, i]; // 距離初始化
s[i] = 0; // s[]置空 0表示i不在s集合中
if (g.edges[v, i] < INF) // 路徑初始化
path[i] = v;
else
path[i] = - 1;
}
s[v] = 1; // 源點編號v放入s中
path[v] = 0;
for (i = 0; i < g.n; i++) // 循環直到所有頂點的最短路徑都求出
{
mindis = INF; // mindis置最小長度初值
for (j = 0; j < g.n; j++) // 選取不在s中且具有最小距離的頂點u
if (s[j] == 0 && dist[j] < mindis)
{
u = j;
mindis = dist[j];
}
s[u] = 1; // 頂點u加入s中
for (j = 0; j < g.n; j++) // 修改不在s中的頂點的距離
if (s[j] == 0)
if (g.edges[u, j] < INF && dist[u] + g.edges[u, j] < dist[j])
{
dist[j] = dist[u] + g.edges[u, j];
path[j] = u;
}
}
Dispath(dist, path, s, g.n, v); // 輸出最短路徑
// PutBothpath(g, dist, path, s, g.n, v, 3);
}
static void initdata()
{
int i, j;
MGraph g;
g.n = 4; g.e = 8;
g.edges = new int[MAXV, MAXV];
g.vexs = new VertexType[MAXV];
// int [,] anArray = new int [2, 4] {{1,2,3,4},{5,6,7,8}};
int[,] a = new int[MAXV, MAXV] {
{ 0, 5,INF, 7},
{INF, 0, 4, 2},
{ 3, 3, 0, 2},
{INF,INF, 1, 0}
};
for (i = 0; i < g.n; i++) // 建立圖的圖的鄰接矩陣
{
for (j = 0; j < g.n; j++)
{
g.edges[i, j] = a[i, j]; ///////////////////////////////////////////// //
}
}
Console.WriteLine( " 各頂點的最短路徑: ");
}
static void initialVexInfo(MGraph g)
{
g.vexs[ 0].VexNo = " 0361 ";
g.vexs[ 0].VexName = " 西安 ";
g.vexs[ 1].VexNo = " 010 ";
g.vexs[ 1].VexName = " 北京 ";
g.vexs[ 2].VexNo = " 0681 ";
g.vexs[ 2].VexName = " 武漢 ";
g.vexs[ 3].VexNo = " 0571 ";
g.vexs[ 3].VexName = " 杭州 ";
}
static void Main( string[] args)
{
int i, j;
MGraph g;
g.n = 4; g.e = 8;
g.edges = new int[MAXV, MAXV];
g.vexs = new VertexType[MAXV];
initialVexInfo(g);
// int [,] anArray = new int [2, 4] {{1,2,3,4},{5,6,7,8}};
int[,] a = new int[MAXV, MAXV] {
{ 0, 5,INF, 7},
{ 5, 0, 4, 1},
{INF, 4, 0,INF},
{ 7, 1,INF, 0}
};
for (i = 0; i < g.n; i++) // 建立圖的圖的鄰接矩陣
{
for (j = 0; j < g.n; j++)
{
g.edges[i, j] = a[i, j];
}
}
Console.WriteLine( " 最小生成樹構成: ");
Dijkstra(g, 0);
Console.ReadKey();
}
}
}