实现基于贪婪技术思想的Dijkstra算法
1)Dijkstra算法的伪代码描述
function Dijkstra(Graph, source):
dist[source] ← 0 // Distance from source to source
prev[source] ← undefined // Previous node in optimal path initialization
for each vertex v in Graph: // Initialization
if v ≠ source // Where v has not yet been removed from Q (unvisited nodes)
dist[v] ← infinity // Unknown distance function from source to v
prev[v] ← undefined // Previous node in optimal path from source
end if
add v to Q // All nodes initially in Q (unvisited nodes)
end for
while Q is not empty:
u ← vertex in Q with min dist[u] // Source node in first case
remove u from Q
for each neighbor v of u: // where v has not yet been removed from Q.
alt ← dist[u] + length(u, v)
if alt < dist[v]: // A shorter path to v has been found
dist[v] ← alt
prev[v] ← u
end if
end for
end while
return dist[], prev[]
end function
2)Dijkstra算法的源代码实现
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include <vector>
#include <algorithm>
using namespace std;
//点
typedef struct Point {
int dis = INT_MAX;
bool visit = false;
};
//输出
void output(vector<Point> p, int start) {
cout << endl;
cout << "最短路径的计算起始点为:" << start << endl;
for (int i = 1; i < p.size(); i++) {
if (i == start)
continue;
if (p[i].dis == INT_MAX)
cout << "点" << i << "的最短路径为:无最短路径" << endl;
else
cout << "点" << i << "的最短路径为:" << p[i].dis << endl;
}
}
//dijkstra算法
void Dijkstra(vector<vector<int> > g) {
int vex = g.size() - 1; //顶点数
int start; //计算最短距离的起点
cout << "输入计算最短路径的点:";
cin >> start;
vector<Point> points(vex + 1); //记录点的信息
for (int i = 1; i <= vex; i++)
points[i].dis = g[start][i]; //初始化dis,记录起点到各点的直接距离
points[start].visit = true; //起点访问
for (int i = 1; i <= vex; i++) {
int MINdis = INT_MAX;
int MINvex = 0;
for (int j = 1; j <= vex; j++) {
if (!points[j].visit && points[j].dis < MINdis) { //找出距离最近的点
MINdis = points[j].dis;
MINvex = j;
}
}
points[MINvex].visit = true; //距离最近的点的最短距离确定
for (int i = 1; i <= vex; i++) //更新dis数组
if (g[MINvex][i] < INT_MAX)
points[i].dis = min(points[i].dis, g[MINvex][i] + points[MINvex].dis);
}
output(points, start); //输出结果
}
int main() {
int vexNum, edgeNum;
cout << "输入顶点个数和边数:";
cin >> vexNum >> edgeNum;
vector<vector<int> > graph(vexNum + 1, vector<int>(vexNum + 1, INT_MAX));
cout << "输入邻接边和权值a b w:" << endl;
int a, b, w;
for (int i = 0; i < edgeNum; i++) {
cin >> a >> b >> w;
graph[a][b] = w;
}
for (int i = 1; i <= vexNum; i++) {
graph[i][i] = 0;
}
Dijkstra(graph); //dij算法
system("pause");
return 0;
}
3)Dijkstra算法的时间效率分析
时间复杂度:O(v^2).
实验思考题:
贪婪技术的基本思想是什么?
基本思想:在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。
说明贪婪技术与动态规划各适用什么情况?
贪婪技术:一般用于解决求最大或最小解,只能用于确定某些问题的可行性范围,不能保证解是最佳的。
动态规划:一般用于解决多阶段决策问题,但当问题规模较大时,不能采用动态规划。