Dijkstra算法,自己理解,简单清晰

/**

* https://blog.csdn.net/YiYeZhiNian/article/details/122217450

* https://blog.csdn.net/Xing_LG/article/details/124864695

*

s e

0 1 2 3 4 5

0 arr[][] = {{0 6 3 N N N}

1 {6 0 2 5 N N}

2 {3 2 0 3 4 N}

3 {N 5 3 0 2 3}

4 {N N 4 2 0 5}

5 {N N N 3 5 0}

1.指定一个节点,例如我们要计算 ‘A’ 到其他节点的最短路径

2.引入两个集合(S、U),S集合包含已求出的最短路径的点(以及相应的最短长度),U集合包含未求出最短路径的点(以及A到该点的路径,注意 如上图所示,A->C由于没有直接相连 初始时为∞)

3.初始化两个集合,S集合初始时 只有当前要计算的节点,A->A = 0,U集合初始时为 A->B = 4, A->C = ∞, A->D = 2, A->E = ∞,敲黑板!!!接下来要进行核心两步骤了

4.从U集合中找出路径最短的点,加入S集合,例如 A->D = 2

5.更新U集合路径,if ( ‘D 到 B,C,E 的距离’ + ‘AD 距离’ < ‘A 到 B,C,E 的距离’ ) 则更新U

6.循环执行 4、5 两步骤,直至遍历结束,得到A 到其他节点的最短路径

*/

#include
#include
using namespace std;

struct Node
{
    int node;
    int pre_node;
    float cost_accumulate;
    Node(int _self,int _pre,float cost = INT32_MAX):
        node(_self)
        ,pre_node(_pre)
        ,cost_accumulate(cost){};
};
bool dijkstra(const vector >& arr,int len,int s,int e)
{
    // 0<= s nodes_resolved,nodes_unresolved;
    nodes_resolved.push_back({s,s,0});
    // init cost ultimate
    for(int i = 0;i0)
    {
        float cost_min = INT32_MAX;
        vector::iterator node_nearst = nodes_unresolved.end();
        for(vector::iterator ite = nodes_unresolved.begin();ite!=nodes_unresolved.end();ite++)
        {
            Node& cur = *ite;
            for(const Node& pre:nodes_resolved)
            {
                float cost = pre.cost_accumulate+arr[pre.node][cur.node];
                if(cost < cur.cost_accumulate)
                {
                    cur.pre_node = pre.node;
                    cur.cost_accumulate = cost;
                }
            }
            if(cur.cost_accumulate < cost_min)
            {
                cost_min = cur.cost_accumulate;
                node_nearst = ite;
            }
        }
        nodes_resolved.push_back(*node_nearst);
        nodes_unresolved.erase(node_nearst);    // 没有在nodes_unresolved的迭代器循环里 erase,不会引起迭代起失效问题
    }
    // result
    // nodes_resolved排好序直接回溯取路径
    auto compare = [](const Node& l,const Node& r)->bool
    {
        return l.node < r.node;    
    };
    std::sort(nodes_resolved.begin(),nodes_resolved.end(),compare);
    int i = e;
    while(i!=s)
    {
        printf("%d ",i);
        i = nodes_resolved[i].pre_node;
    }
    printf("%d\t\n",i);
    return true;
}
#define N INT16_MAX
int main(int argc,char* argv[])
{
    int len = 6;
    vector >arr(len);
    //      0 1 2 3 4 5
    arr = {{0,6,3,N,N,N},  // 0
           {6,0,2,5,N,N},  // 1
           {3,2,0,3,4,N},  // 2
           {N,5,3,0,2,3},  // 3
           {N,N,4,2,0,5},  // 4
           {N,N,N,3,5,0}}; // 5
    dijkstra(arr,len,0,5);
}

你可能感兴趣的:(算法,数据结构)