编程实现用 :用 Dijkstra Algorithm,分别找出点节点2~6至至节点1的最短路径,并指出该最短路径经过的节点

作业要求:

图中圆形表示6个节点,节点间连线及数字表示节点间双向通信链路及链路权值。请将图中的值未知权值abc分别替换为本人学号的后3位,3位数字中为0的,统一将0替换为3,学号后3位为410,此时:a=4 、b=1 、c=3

编程实现用 :用 Dijkstra Algorithm,分别找出点节点2~6至至节点1的最短路径,并指出该最短路径经过的节点。

运行环境:

Eclipse IDE for Java Developers - 2020-06

题目分析:

将学号后三位410替换后,图形如下图所示:

由题目要求,找出点节点2~6至节点1的最短路径,可以看作是分别求节点1到节点2~6的路径。

算法介绍:

迪杰斯特拉(Dijkstra)算法

迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止

下面使用Dijkstra算法分析题目:

(算法实现原理)

下面开始求顶点 A 到各个顶点的最短距离

首先第一步 声明一个far数组表示节点1到各节点的距离编号0~6

顶点所对应的值为节点1到当前节点的距离,如far[1] =1即表示节点1到节点2的距离为1

将数组初始化
因为1节点到1节点的距离为0所以将far[0] 的值初始化为0
其他节点我们假设起点1到它们的距离为无穷大

继续声明一个数组already_visited表示节点是否已经被访问
同样的0-5表示节点1~6  六个顶点, yes表示当前节点已经被访问过 ,no表示当前节点还未被访问过

继续声明一个parent数组表示当前节点的父节点 即当前正在处理的节点的前一个顶点
将parent [0]的值初始化为-1 ,因为节点1是第一个处理的节点 ,所以没有父节点这里用-1表示

下面开始演示Dijkstra算法的步骤

(算法实现及流程)

1.遍历所有未访问的节点 取距离1点距离最小的节点,此时的节点为1节点,其他节点到1节点的距离都为无穷大

遍历1节点的所有未访问过的子节点(即 5 和2和4节点) ,此时far数组中5和2和4到1的距离都为无穷大,大于5、2和4到1的距离5、1和3所以将节点5和节点2和节点4到节点1的距离更新到far数组即 far[4]=5,far[1]=1, far[3]=3

更新节点5、4、2的父节点为节点1即parent [4]=,parrent[1]=0,parrent[3]=0。 最后将节点1标记为已访问(yes)。

第一次遍历结束后如下图表格所示:

2.遍历所有未标记为已访问的节点,取距离节点1最近的节点2,遍历节点2点的所有未访问的节点4、6、3

将节点4与1的距离far[3]更新为far[1]+1=2<3,故更新节点4信息,父节点更新为parent [3]=1,并将2节点标记为已访问(yes)

将节点3与1的距离far[2]更新为far[1]+4=5,父节点更新为parent [2]=1

将节点6与1的距离far[5]更新为far[1]+3=4,父节点更新为parent [5]=1

第二次遍历结束后如下图表格所示:

3.继续遍历所有未标记为已访问的节点,取距离节点2最近的节点4,遍历节点4点的所有未访问的节点5、6,并将4节点标记为已访问(yes)

将节点5与1的距离far[4]更新为far[3]+1=3<5,故更新节点5信息,父节点更新为parent [3]=3

将节点6与1的距离far[4]更新为far[3]+1=3<4,故更新节点6信息,父节点更新为parent [5]=3

第三次遍历结束后如下图表格所示:

4.继续遍历所有未标记为已访问的节点,取距离节点4最近的节点5,遍历节点5点的所有未访问的节点6,并将5节点标记为已访问(yes)

将节点6与1的距离far[4]为far[4]+3=8>3,故不更新节点5信息。

取距离节点4最近的节点6,遍历节点6点的所有未访问的节点3,并将3节点标记为已访问(yes)

将节点3与1的距离far[2]为far[5]+1=4<5,故更新节点.3信息,父节点更新为parent [2]=5

5.遍历所有未标记为已访问的节点,取距离6最近的节点3,遍历发现3已经没有子节点可以访问 所以将3节点标记为已访问

6.此时图中的所有节点都已经被访问至此、得到两个数组 far和parent

far中对应的值即为1节点到相应点的最短距离
例如: 1点到6点的最短距离为:distance[5] =3

1点到5点的最短距离为:distance[4]=3

并通过parent数组进一步得到最短路径是沿着那一条路径走的

例如:求6到1的最短路径走法

从6开始 定位到parent[6] 值为1即对应的4节点索引parent [3],继续定位到parent [3]父节点为parent [1],parent [1]继续定位到parent [0] 值为-1 结束

此时得到的路径为 6->4->2->1为6节点到1节点的最短路径。

JAVA代码实现结果如下:

部分源码(全部源码见附件):

①创建表示节点距离间的矩阵

public static void main(String[] args) {

        //表示节点的值

        char[] vertex = {'1', '2', '3', '4', '5', '6'};

        int[][] matrix = new int[vertex.length][vertex.length];

        final int M = Integer.MAX_VALUE; //表示一个无穷值  表示两个节点之间不连通

        //使用一个6x6的矩阵表示几点直接的关系 值表示 节点直接的距离

                                 //1  2  3  4  5  6 

        /*1*/matrix[0] = new int[]{M, 1, M, 3, 5, M};

        /*2*/matrix[1] = new int[]{1, M, 4, 1, M, 3};

        /*3*/matrix[2] = new int[]{M, 4, M, M, M, 1};

        /*4*/matrix[3] = new int[]{3, 1, M, M, 1, 1};

        /*5*/matrix[4] = new int[]{5, M, M, 1, M, 3};

        /*6*/matrix[5] = new int[]{M, 3, 1, 1, 3, M};

       

        manguanwen dijkstraCase = new manguanwen(vertex, matrix);

        dijkstraCase.dijkstra(0, 6);

    }

②判断节点是否已经被标记

声明一个数组already_arr表示节点是否已经被访问
同样的0-5表示节点1~6  六个顶点, yes表示当前节点已经被访问过,对应
boolean值为true ,no表示当前节点还未被访问过,对应boolean值为false.

// 判断所有的所有的节点是否已经被标记

    public boolean IsFinished() {

        for (boolean b : already_arr) {

            if (!b) {

                return false;

            }

        }

        return true;

    }

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

man1669

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值