单源最短路径问题(Java)

文章目录

  • 单源最短路径问题(Java)
    • 1、问题描述
    • 2、算法思路
    • 3、代码实现
    • 4、算法正确性和计算复杂性
      • 4.1 贪心选择性质
      • 4.2 最优子结构性质
      • 4.3 计算复杂性
    • 5、参考资料


1、问题描述

给定带权有向图G=(V,E),其中每条边的权是非负实数。另外,还给定V中的一个顶点, 称为。现在要计算从源到所有其他各顶点的最短路长度。这里路的长度是指路上各边权之和。这个问题通常称为单源最短路径问题

其中,V表示顶点集合,E表示各个节点之间的边。

2、算法思路

对于单源最短路径问题,Dijkstra算法是解决这个问题的贪心算法。

基本思想

设置顶点集合S并不断地做贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。

初始时,S 中仅含有源。设u是G 的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u 的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度

Dijkstra 算法每次从v-s中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组dist 进行必要的修改。一旦S包含了所有V中顶点,dist数组就记录了从源到所有其他顶点之间的最短路径长度。

Dijkstra 算法可描述如下。

其中, 输入的带权有向图是G = (V, E) , V = {1 , 2, …, n} 。顶点v是源。a是一个二维数组,a[i][j]表示边(i,j)的权。当(i, j) 时,a[i][j]是一个大数。如dist[i]表示当前从源到顶点t的最短特殊路径长度。

3、代码实现

例如,对下图中的有向图,应用Dijkstra算法计算从源顶点1到其它顶点间最短路径的过程列在下页的表中。

题目示意图

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;/*** TODO  1 --> 4 --> 3 --> 5*/
public class Solution {private static int vNum, eNum;private static int[] v;private static float[][] e;public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.print("input the number of vertix and edge:");vNum = scanner.nextInt();eNum = scanner.nextInt();v = new int[vNum];e = new float[vNum + 1][vNum + 1];for (int i = 0; i < e.length; i++) {for (int j = 0; j < e.length; j++) {e[i][j] = Float.MAX_VALUE;}}System.out.print("input the vertix information:");for (int i = 0; i < v.length; i++) {v[i] = scanner.nextInt();}System.out.println("input the weight of edges:");for (int i = 0; i < eNum; i++) {int start = scanner.nextInt(), target = scanner.nextInt();e[start][target] = (float) scanner.nextInt();}System.out.print("顶点有:");for (int i = 0; i < v.length; i++) {if (i == v.length - 1) {System.out.println(v[i]);} else {System.out.print(v[i] + ", ");}}System.out.println("边与边之间的距离:");for (int i = 1; i < e.length; i++) {for (int j = 1; j < e.length; j++) {if (i != j && e[i][j] != Float.MAX_VALUE) {System.out.print("[" + i + ", " + j + "] = " + e[i][j] + "; ");}}}System.out.println();int[] path = new int[vNum + 1];float[] dist = new float[vNum + 1];Dijkstra(v[0], e, dist, path);System.out.print("Dijkstra路径为:");List<Integer> list = new ArrayList<>();list.add(vNum);list.add(path[vNum]);while (true) {if (path[list.get(list.size() - 1)] == 1) {list.add(1);break;}list.add(path[list.get(list.size() - 1)]);}for (int j = list.size() - 1; j >= 0; j--) {if (j != 0) {System.out.print(list.get(j) + "-->");} else {System.out.println(list.get(j));}}System.out.println("从顶点1到各顶点最短距离:");for (int i = 1; i < dist.length; i++) {System.out.println("dist[" + i + "] = " + dist[i]);}}public static void Dijkstra(int vertix, float[][] weight, float[] dist, int[] path) {int n = dist.length - 1;if (vertix < 1 || vertix > n + 1) {return;}boolean[] vis = new boolean[n + 2];// initializefor (int i = 1; i <= n; i++) {dist[i] = weight[vertix][i];vis[i] = false;if (dist[i] == Float.MAX_VALUE) {path[i] = 0;} else {path[i] = vertix;}}dist[vertix] = 0;vis[vertix] = true;for (int i = 1; i < n; i++) {float tmp = Float.MAX_VALUE;int u = vertix;for (int j = 1; j <= n; j++) {if ((!vis[j]) && (dist[j] < tmp)) {u = j;tmp = dist[j];}}vis[u] = true;for (int j = 1; j <= n; j++) {if ((!vis[j]) && (weight[u][j] < Float.MAX_VALUE)) {float newDist = dist[u] + weight[u][j];if (newDist < dist[j]) {dist[j] = newDist;path[j] = u;}}}}}
}

运行结果

Dijkstra算法的迭代过程:


图解过程

4、算法正确性和计算复杂性

4.1 贪心选择性质

(1)根据算法可知,最短距离是最小的路长,故
dist[x]<= d(v,x)

(2)假设存在另外一条更短路红色线所示,故
d(v,x)+d(x,u)=d(v,u)<dist[u]

(3)由(1)(2)可知,dist[x]<dist[u]。此为矛盾,因为如果(3)成立,此时应该选择 x进入S集合,即选择具有最短特殊路径的顶点是x,而不是u。(因为根据最短路径算法,总是选取最短路径的顶点进入S)

4.2 最优子结构性质

该性质描述为:如果S(i,j)={Vi…Vk…Vs…Vj}是从顶点i到j的最短路径,k和s是这条路径上的一个中间顶点,那么S(k,s)必定是从k到s的最短路径。下面证明该性质的正确性。

假设S(i,j)={Vi…Vk…Vs…Vj}是从顶点i到j的最短路径,则有S(i,j)=S(i,k)+S(k,s)+S(s,j)。而S(k,s)不是从k到s的最短距离,那么必定存在另一条从k到s的最短路径S’(k,s),那么S’(i,j)=S(i,k)+S’(k,s)+S(s,j)<S(i,j)。则与S(i,j)是从i到j的最短路径相矛盾。因此该性质得证。

4.3 计算复杂性

对于具有n个顶点和e条边的带权有向图, 如果用带权邻接矩阵表示这个图,那么Dijkstra算法的主循环体需要O(n) 时间。这个循环需要执行n-1次,所以完成循环需要
0(n2)时间。算法的其余部分所需要时间不超过0(n2)。

5、参考资料

  • 算法设计与分析(第四版)

单源最短路径问题(Java)相关推荐

  1. Dijkstra 单源最短路径算法 Java实现

    Dijkstra 单源最短路径算法 Java实现 算法导入 算法核心 复杂度分析 时间复杂度 空间复杂度 代码实现 参考资料 结尾 算法导入 在图论中,求最短路径有一个经典的算法 Dijkstra算法 ...

  2. java有向图最短路径_单源最短路径之Java实现(使用Java内置优先队列)

    import java.util.*; /** * 用堆实现了从一个点到其他点的最短路径 * @author 李赫元 */ public class ShortestPath { /**有n个节点*/ ...

  3. 用java单源最短路径问题_单源最短路径-贪心算法

    单源最短路径,关于这个问题的贪心算有点不好理解,分析后续补充,代码也需要后续优化,便于理解 package test; import java.util.ArrayList; import java. ...

  4. 用java编写的一个迪杰斯特拉算法(单源最短路径算法,Dijkstra算法)。

    可以用于有向图和无向图.用负数表示该有向路不通.在EditPlus上写的,所以就一个.java文件. package Test;import java.util.TreeMap; import jav ...

  5. 用java单源最短路径问题_java 单源最短路径问题

    import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util ...

  6. p3371 单源最短路径(弱化版)-java题解-最短路

    弱化版传送门: P3371 [模板]单源最短路径(弱化版) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目背景 本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通 ...

  7. p4779 单源最短路径(标准版)-java版

    传送门: P4779 [模板]单源最短路径(标准版) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P4779 先给 ...

  8. 单源最短路径问题——分支限界法(Java)

    1. 前置芝士 1.1 分支限界法求解目标 分支限界法与回溯法的不同求解目标: 回溯法的求解目标:找出解空间树中满足约束条件的所有解: 分支限界法的求解目标:找出满足约束条件的一个解,或是在满足约束条 ...

  9. 分支限界法 java_算法java实现–分支限界法–单源最短路径问题 | 学步园

    单源最短路径问题的java实现(分支限界法) 具体问题描述以及C/C++实现参见网址 http://blog.csdn.net/liufeng_king/article/details/8900872 ...

最新文章

  1. Android Activity 和 ViewGroup中事件触发和传递机制
  2. 这款Linux发行版已经适配200+移动设备
  3. 某互联网企业技术发展史(四)配置nginx和mysql兼容Yii框架,上传网站并调试成功...
  4. SAP S/4HANA客户关系管理之变
  5. 深入理解重要的编程模型
  6. LOJ:相框(欧拉回路、分类讨论)
  7. 第五十期:工作强度超996,失业半年即出局,硅谷为何如此“嗜血”?
  8. MaxCompute 存储设计
  9. Python命令行参数
  10. android 右边抽屉,android – 抽屉在右侧抽屉中切换
  11. 中对缺失数据的预处理_数据预处理也有套路的
  12. 运维技术之二(2)、docker安装jumpserver
  13. Rviz教程系列第一章之Markers
  14. 小战Java笔记_SE_Identifier(标识符)
  15. Android、Java超详细的身份证验证工具
  16. 三星s8android9,三星S8官方国行版安卓9固件rom刷机包:CHC-G9500ZCS3DSD5
  17. C语言入门-绝对值(abs)
  18. 服务器设置防火墙网站打不开,部分网站打不开如何处理?
  19. aix 到 linux的网络,通过VIOS实现AIX系统的网络虚拟化
  20. left.php源代码分析

热门文章

  1. drupal上安装chatroom
  2. 初识QT(十二)——VS中使用Qt方法详解
  3. java统计点击量每秒100万_这速度嗖嗖嗖!V神:以太坊网络每秒处理量将超100万次...
  4. winbox设置端口映射
  5. 视觉检测之3D视觉概述
  6. 电信3g手机僵局中国it
  7. deepin安装瑞昱Realtek无线网卡8188GU驱动
  8. window系统清理软件 哪个好
  9. 软件测试5班第一天课程,软件测试知识扫盲
  10. 计算机毕业设计Java宠物医院管理系统(源码+系统+mysql数据库+lw文档