图论课笔记--最短路问题

一、问题概述

    定义:在给定赋权图G及图G中两点u、v,求u到v具有最小权重的路的问题叫做最短路问题。

解决问题的算法主要有:

  • Dijkstra算法
  • Bellman-Ford 算法
  • Floyd-Warshall算法
本文仅粗略的描述一下Dijkstra算法。
二、Dijkstra算法
  •   算法特点

         Dijkstra算法使用了广度优先搜索解决赋权有向图或者无向图的单源最短路径问题,算法最终得到一个最短路径树

  • 算法思路
          Dijkstra 算法采用的是一种 贪心的策略 ,声明一个数组 dis 来保存源点到各个顶点的最短距离和一个保存已经找到了最短路径的顶点的集合:T ,初始时,原点 s 的路径权重被赋为 0 (dis[s] = 0 )。若对于顶点 s 存在能直接到达的边( s,m ),则把 dis[m] 设为 w s, m , 同时把所有其他( s 不能直接到达的)顶点的路径长度设为无穷大。
         初始时,集合T 只有顶点 s。 然后,从dis 数组选择最小值,则该值就是源点 s 到该值对应的顶点的最短路径,并且把该点加入到T中, OK ,此时完成一个顶点,然后,我们需要看看新加入的顶点是否可以到达其他顶点并且看看通过该顶点到达其他点的路径长度是否比源点直接到达短,如果是,那么就替换这些顶点在dis 中的值。
         然后,又从 dis 中找出最小值, 重复上述动作 ,直到 T 中包含了图的所有顶点
三、代码实现
 /**
  * Dijkstra 算法
  */
public static int[] dijkstra(int[][] weight, int start) {
    // 接受一个有向图的权重矩阵,和一个起点编号start(从0编号,顶点存在数组中)
    // 返回一个int[] 数组,表示从start到它的最短路径长度
    int n = weight.length; // 顶点个数
    int[] shortPath = new int[n]; // 保存start到其他各点的最短路径
    String[] path = new String[n]; // 保存start到其他各点最短路径的字符串表示
    for (int i = 0; i < n; i++)
        path[i] = new String(start + "-->" + i);
    int[] visited = new int[n]; // 标记当前该顶点的最短路径是否已经求出,1表示已求出

    // 初始化,第一个顶点已经求出
    shortPath[start] = 0;
    visited[start] = 1;

    for (int count = 1; count < n; count++) { // 要加入n-1个顶点
        int k = -1; // 选出一个距离初始顶点start最近的未标记顶点
        int dmin = Integer.MAX_VALUE;
        for (int i = 0; i < n; i++) {
            if (visited[i] == 0 && weight[start][i] < dmin) {
                dmin = weight[start][i];
                k = i;
            }
        }

        // 将新选出的顶点标记为已求出最短路径,且到start的最短路径就是dmin
        shortPath[k] = dmin;
        visited[k] = 1;

        // 以k为中间点,修正从start到未访问各点的距离
        for (int i = 0; i < n; i++) {
            //如果 '起始点到当前点距离' + '当前点到某点距离' < '起始点到某点距离', 则更新
            if (visited[i] == 0 && weight[start][k] + weight[k][i] < weight[start][i]) {
                weight[start][i] = weight[start][k] + weight[k][i];
                path[i] = path[k] + "-->" + i;
            }
        }
    }
    for (int i = 0; i < n; i++) {

        System.out.println("从" + start + "出发到" + i + "的最短路径为:" + path[i]);
    }
    return shortPath;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值