zoukankan      html  css  js  c++  java
  • Dijkstra算法

    Dijkstra 最短路径算法

    输入: 图G=(V,E),V是点集合,E是边集合和原点s

    集合X:已经被处理的点集合,初始化:仅包含原点s。

    distTo[s]=0初始化s点的距离为0,其他点为无穷大

    伪代码: 

    (1) while (集合X$ eq$V)

    (2)遍历所有的边$(v,w) in E$ 

    其中$v in X$,$w otin X$

    选择一条边能够使得当前$distTo[v] + l_{vw}$达到最小。

    (3)将该点$w$加入X集合中。

    (4)更新当前distTo[w]的值。重复上述过程,直到while结束。

    1 未优化的C++ Dijkstra算法代码如下,复杂度为$O(mn)$,$n$为顶点数,$m$为边数,,运行时间为::0.037477s

        Dijkstra(Graph graph, int s)
        {
            distInit();        
            marked.push_back(s);//将原点加入集合X中
            distTo[s] = 0; //原点距离初始化为0
            /***当集合X点不包括图中的顶点时****/
            while(marked.size() < length)  
            {
                long int min = maxInt;
                int index1, index2, indexMin;
                /******marked:be added to set X,集合X中的点******/
                for(int i = 0; i < marked.size(); i++) 
                {
                    EdgeNode *p = new EdgeNode(0,NULL);
                    p = (graph.adjList+marked[i])->firstEdge;
                    index1 = marked[i];//集合X中的点
                    while(p)
                    {
                        //try to traversed edges whose head is not in set X, tail in set X.
                        if(min > p->weight + distTo[index1] && !is_marked(p->adjvex))
                        {
                            indexMin = index1;//标记最小索引
                            min = p->weight + distTo[index1];
                            index2 = p->adjvex;//集合X之外的点
                        }
                        p = p->next;
                    }
                }
                //如果找到了最小路径
                if(min < maxInt)
                {
                    marked.push_back(index2);//将该点添加到集合X中
                    distTo[index2] = min;//距离更新
                    path[index2].insert(path[index2].begin(),path[indexMin].begin(),path[indexMin].end());//路径更新
                    path[index2].push_back(index2);
                }
            }
            
        }

    2.用优先队列优化后的代码,实现得有点问题,运行时间为:0.010996s

        Dijkstra(Graph graph, int s)
        {
            priority_queue<int, vector<int>, greater<int> > myQueue;//优先队列
            distInit();//距离初始化,原点距离为0其余各点距离初始化为无穷大
            myQueue.push(s);
            while(!myQueue.empty())
            {
                VertexNode *temp = new VertexNode;    
                EdgeNode *p = new EdgeNode(0,NULL);
                temp = (graph.adjList + myQueue.top());
                p = (graph.adjList + myQueue.top())->firstEdge;
                myQueue.pop(); //将该点弹出
                while(p)//遍历与该点相连的点
                {
                    /*************找到能够更新的,压入队列******************/
                    if(distTo[p->adjvex] > distTo[temp->data] + p->weight)
                    {
                        myQueue.push(p->adjvex);
                        distTo[p->adjvex] = distTo[temp->data] + p->weight;
                        //路径更新
                        edgeTo[p->adjvex].clear();            
                        edgeTo[p->adjvex].insert(edgeTo[p->adjvex].begin(),edgeTo[temp->data].begin(),edgeTo[temp->data].end());
                        edgeTo[p->adjvex].push_back(p->adjvex);
                    }
                    p = p->next;
                }
            }
        }

    3.图的存储

    /***********边表***********/
    class EdgeNode
    {
    public:
        int adjvex;
        int weight;
        EdgeNode *next;
        EdgeNode(long int adj, EdgeNode *n = NULL): adjvex(adj), next(n){}
    
    };
    /************顶点表*************/
    class VertexNode 
    {
    public:
        long int data;
        EdgeNode *firstEdge;
    
    };

     4.完整代码

    https://github.com/Shinered/Dijkstra_algorithm/blob/master/test1.cpp

    The Safest Way to Get what you Want is to Try and Deserve What you Want.
  • 相关阅读:
    MongoDB
    Redis主从复制
    在Flash中动画的制作方式:
    帧的类型:
    第一次做的补间动画,总结过程
    Python脚本:过滤取指定链接标题是否含有指定文字,并将其输出
    cmd命令:在ftp下载文件运行
    bat命令:在txt文本每行后加指定文字
    bat命令:在txt文本每行前加指定文字
    SSH爆破心得:
  • 原文地址:https://www.cnblogs.com/Shinered/p/9019624.html
Copyright © 2011-2022 走看看