C语言学习Day20

实现基于贪婪技术思想的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).

实验思考题:

贪婪技术的基本思想是什么?

        基本思想:在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。

说明贪婪技术与动态规划各适用什么情况?

    贪婪技术:一般用于解决求最大或最小解,只能用于确定某些问题的可行性范围,不能保证解是最佳的。
    动态规划:一般用于解决多阶段决策问题,但当问题规模较大时,不能采用动态规划。

猜你喜欢

转载自blog.51cto.com/14947752/2547570