C++版Dijkstra最短路徑算法
/////////////////////////////////////////////////////////////////////////////////////
//file:ShortestPath.h
#ifndef _SHORTESTPATH_H_
#define _SHORTESTPATH_H_
#define MAX_NODES 100
#define INFINITY 100
#include <iostream>
using namespace std;
class Vertex { //頂點類
public:
Vertex(int i = -1) {
id = i; //頂點標號 初始化爲-1
known = false; //打圈的標記 初始化爲false
dist = INFINITY; //距離 初始化爲正無窮
pred = -1; //頂點的前一個點 初始化爲-1
}
int id;
bool known;
int dist;
int pred;
};
class Path { //路徑類
public:
Path() {
_start = MAX_NODES; //開始下標 初始化爲MAX_NODES
for(int i = 0; i < MAX_NODES; i++)
_path[i] = -1; //初始路徑初始化爲-1
}
int in_path(int item) { //寫入一個路徑頂點
_start--;
_path[_start] = item;
return 0;
}
int de_path(int& item) { //輸出一個路徑頂點
item = _path[_start];
_start++;
return 0;
}
bool is_empty() const{
if(_start == MAX_NODES) return true;
else return false;
}
private:
int _start;
int _path[MAX_NODES];
};
class Graph { //圖類
public:
Graph() {
_num_nodes = 0; //初始化頂點數爲0 權值矩陣均爲正無窮
for(int i = 0; i < MAX_NODES; i ++)
for(int j = 0; j < MAX_NODES; j ++)
_weight[i][j] = INFINITY;
}
int build(string ifile); //從文件中讀取數據建立圖
Path shortest_path(int S, int T); //計算從S到T的最短路徑
private:
int _num_nodes; //頂點總數
Vertex Vex[MAX_NODES]; //頂點的集合
int _weight[MAX_NODES][MAX_NODES]; //權值矩陣
};
#endif
//////////////////////////////////////////////////////////////////////////////////////
//file:ShortestPath.cpp
#include "ShortestPath.h"
#include <fstream>
int Graph::build(string ifile) { //從文件數據中創建圖
int i = 0;
int j = 0;
ifstream infile(ifile.c_str());
if(!infile) {
cout << "Error: Unable to open the input file!" << ifile.c_str() << endl;
exit(-1);
}
infile >> _num_nodes; //讀取節點總數
while(infile >> i) {
if(i >= _num_nodes) {
cout << "The node does not exist!" << endl;
exit(-1);
}
infile >> j;
if(j >= _num_nodes) {
cout << "The node does not exist!" << endl;
exit(-1);
}
infile >> _weight[i][j]; //讀取權值
}
infile.close();
for(int i = 0; i < _num_nodes; i++) { //建立頂點
Vex[i] = Vertex(i);
}
return 0;
}
Path Graph::shortest_path(int S, int T) { //求從S到T的最短路徑
Path path;
int next = -1;
if(_num_nodes == 0) { //判空
cout << "The graph is empty!" << endl;
exit(-1);
}
if(S < 0 || T < 0 || S >= _num_nodes || T >= _num_nodes) { //檢查節點是否存在
cout << "Node S or T does not exist!" << endl;
exit(-1);
}
int current = S;
Vex[S].dist = 0;
while(Vex[T].known == false) {
int smallest_d = INFINITY;
for(int i = 0; i < _num_nodes; i++) {
if(Vex[i].known == false) {
if(Vex[current].dist + _weight[current][i] < Vex[i].dist) {
Vex[i].dist = Vex[current].dist + _weight[current][i];
Vex[i].pred = current;
}
if(Vex[i].dist < smallest_d) {
smallest_d = Vex[i].dist;
next = i;
}
}
}
current = next;
Vex[current].known =true;
}
path.in_path(T); //將路徑存入path
current = T;
while(current != S) {
path.in_path(Vex[current].pred);
current = Vex[current].pred;
}
return path;
}
//////////////////////////////////////////////////////////////////////////////////////
//file:main.cpp
#include "ShortestPath.h"
ostream& operator<<(ostream& out, Path& path) { //重載輸出運算符
int item = -1;
while(!path.is_empty()) {
path.de_path(item);
out << "-->" << item;
}
return out;
}
int main() {
int S = 0;
int T = 6;
string file_name = "data.txt";
Graph G;
G.build(file_name);
Path path;
path = G.shortest_path(S, T);
cout << path;
return 0;
}