Dijkstra算法(一)

  由于准备美赛,所以提前看一下相关书籍。

参考:数据建模算法与应用(第二版),https://blog.csdn.net/lbperfect123/article/details/84281300

简要

Dijkstra算法是典型最短路算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。

Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。

Dijkstra一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表方式,Drew为了和下面要介绍的 A* 算法和 D* 算法表述一致,这里均采用OPEN,CLOSE表的方式。

其采用的是贪心法的算法策略

大概过程:

创建两个表,OPEN, CLOSE。

OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。

1. 访问路网中距离起始点最近且没有被检查过的点,把这个点放入OPEN组中等待检查。

2. 从OPEN表中找出距起始点最近的点,找出这个点的所有子节点,把这个点放到CLOSE表中。

3. 遍历考察这个点的子节点。求出这些子节点距起始点的距离值,放子节点到OPEN表中。

4. 重复第2和第3步,直到OPEN表为空,或找到目标点。

实例:

具体以书中例子为例:

eg:某公司在6个城市c1,c2,c3,c4,c5中有分公司,从c1到cj的直接航程票价记在下属邻接矩阵中(空格代表无效)。寻找一条c1到其他城市的最便宜的路线。

 12040  
120     40 20
30     20 30
  40 20    
20   30    

Matlab:

clc,clear;
a=zeros(5);
a(1,3)=40;a(1,2)=120;
a(2,5)=20;a(2,4)=40;
a(3,4)=20;a(3,5)=30;
a = a+a';
a(a==0)=inf
pb(1:length(a))=0;pb(1)=1;index1=1;result=5;index2=ones(1,length(a));index3=index1;
d(1:length(a))=inf;d(1)=0;minn=d(result);
temp=1;
while sum(pb)<length(a)
    tb = find(pb==0);
    d(tb)=min(d(tb),d(temp)+a(temp,tb)); 
    if d(result)~=minn
        index3=[index3,temp];
    end
    tmpb=find(d(tb)==min(d(tb)));
    temp=tb(tmpb(1));
    pb(temp)=1;
    index1=[index1,temp];minn=d(result);
    temp2=find(d(index1)==d(temp)-a(temp,index1));
    index2(temp)=index1(temp2(1));
end
index3=[index3,result];
d,index1,index2,index3

 

 

 

 

 

 变量解释:index1,index2,index3分别用来存放标号信息的,标号定点顺序,标号顶点索引,从始点到终点(result)的通路。

index2存放起始点到第i点的最短通路的第i顶点前一顶点的序号。

例如上述示例,c1到c5的通路为1->3->5。

当然,在记录路径信息的时候也可参照下面C++的方法把所有的最短通路的信息都显示出来(通过index2)。

C++:

#include<fstream>
#define MaxNum 765432100
using namespace std;

ifstream fin("Dijkstra.in.txt");
ofstream fout("Dijkstra.out.txt");

int Map[100][100];
bool is_arrived[100];
int Dist[100], From[100], Stack[100];
int p, q, k, Path, Source, Vertex, Temp, SetCard;

int FindMin()
{
    int p, Temp = 0, Minm = MaxNum;
    for (p = 1; p <= Vertex; p++)
        if ((Dist[p] < Minm) && (!is_arrived[p]))
        {
            Minm = Dist[p];
            Temp = p;
        }
    return Temp;
}
int main()
{
    memset(is_arrived, 0, sizeof(is_arrived));

    fin >> Source >> Vertex;
    for (p = 1; p <= Vertex; p++)
        for (q = 1; q <= Vertex; q++)
        {
            fin >> Map[p][q];
            if (Map[p][q] == 0) Map[p][q] = MaxNum;
        }
    for (p = 1; p <= Vertex; p++)
    {
        Dist[p] = Map[Source][p];
        if (Dist[p] != MaxNum)
            From[p] = Source;
        else
            From[p] = p;
    }

    is_arrived[Source] = true;
    SetCard = 1;
    do
    {
        Temp = FindMin();
        if (Temp != 0)
        {
            SetCard = SetCard + 1;
            is_arrived[Temp] = true;
            for (p = 1; p <= Vertex; p++)
                if ((Dist[p] > Dist[Temp] + Map[Temp][p]) && (!is_arrived[p]))
                {
                    Dist[p] = Dist[Temp] + Map[Temp][p];
                    From[p] = Temp;
                }
        }
        else
            break;
    } while (SetCard != Vertex);

    for (p = 1; p <= Vertex; p++)
        if (p != Source)
        {
            fout << "========================\n";
            fout << "Source:" << Source << "\nTarget:" << p << '\n';
            if (Dist[p] == MaxNum)
            {
                fout << "Distance:" << "Infinity\n";
                fout << "Path:No Way!";
            }
            else
            {
                fout << "Distance:" << Dist[p] << '\n';
                k = 1;
                Path = p;
                while (From[Path] != Path)
                {
                    Stack[k] = Path;
                    Path = From[Path];
                    k = k + 1;
                }
                fout << "Path:" << Source;
                for (q = k - 1; q >= 1; q--)
                    fout << "-->" << Stack[q];
            }
            fout << "\n========================\n\n";
        }

    fin.close();
    fout.close();
    return 0;
}

结果:

========================
Source:1
Target:2
Distance:90
Path:1-->3-->5-->2
========================

========================
Source:1
Target:3
Distance:40
Path:1-->3
========================

========================
Source:1
Target:4
Distance:60
Path:1-->3-->4
========================

========================
Source:1
Target:5
Distance:70
Path:1-->3-->5
========================

 lingo解法请见Dijkstra 二。https://www.cnblogs.com/a-runner/p/14305894.html

posted @ 2021-01-20 22:13  为红颜  阅读(388)  评论(0编辑  收藏  举报