Java动态规划实现最短路径问题
问题描述
给定一个加权连通图(无向的或有向的),要求找出从每个定点到其他所有定点之间的最短路径以及最短路径的长度。
2.1 动态规划法原理简介
动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。具体的动态规划算法多种多样,但它们具有相同的填表格式。
与分治法最大的差别是:适合于用动态规划法求解的问题,经分解后得到的子问题往往不是互相独立的(即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解)
package com.liuzhen.floyd;
public class Floyd {
//根据有向图的权重矩阵及起始的中间节点路径矩阵,返回最终图的距离矩阵及中间节点路径矩阵
public static void getShortestPath(int[][] chart,int[][] path){
int len = chart.length;
for(int k = 0;k < len;k++){ //k = 0表示,增加中间顶点a,k自增,表示后继增加第k个中间顶点(依次为b,c,d...)
for(int i = 0;i < len;i++){
for(int j = 0;j < len;j++){
int temp = 0; //新增一个中间顶点时,用该变量存储从i到k再到j的路径长度
if(chart[i][k] != 100 && chart[k][j] != 100) //当A[i][k]和A[k][j]路径都可以行走,100表示两顶点不相通
temp = chart[i][k] + chart[k][j];
if(chart[i][j] > temp && temp != 0) { //如果当前i到j路径长度(包括无法达到情况)大于以k为中间顶点的路径时
chart[i][j] = temp;
path[i][j] = k+1; //当两顶点相通,且是最短路径时,把k+1存入中间节点路径矩阵path中(PS:0表示i到j之间没有中间节点,1表示中间节点为a,所以此处为k+1,而不是用k,这样排除0的情况)
}
}
}
}
}
//根据有向图的中间节点路径矩阵,以及两个顶点,返回这两个顶点之间的最短路径
public static String getOneShortestPath(int[][] path,int start,int end){
char startNode = (char) ('a' + start);
char endNode = (char) ('a' + end);
String nodePath = "";
if(path[start][end] == 0){
nodePath += startNode+"->"+endNode;
return nodePath;
}
int middle = path[start][end]-1;
//使用递归求解最短路径
nodePath += getOneShortestPath(path,start,middle)+" , "+getOneShortestPath(path,middle,end);
return nodePath;
}
//输出有向图所有顶点之间的最短路径及最短路径长度
public static void printShortestPath(int[][] path,int[][] result){
int len = path.length;
for(int i = 0;i < len;i++){
char startNode = (char) ('a' + i);
for(int j = 0;j < len;j++){
char endNode = (char) ('a' + j);
String ijPath = startNode+"——>"+endNode+"最短路径为:";
String nodePath = getOneShortestPath(path,i,j);
System.out.println(ijPath+nodePath+" 。 路径长度为:"+result[i][j]);
}
}
}
public static void main(String args[]){
/*chart数组中,数组0,1,2,3等表示两顶点之间的权重值,即两顶点间的距离大小, 100表示两顶点不相通*/
int[][] chart = {{0,100,3,100},{2,0,100,100},{100,7,0,1},{6,100,100,0}};
System.out.println("有向图chart的权重矩阵为(PS:其中值为100表示无穷大,即无法相通的路径):");
System.out.println("\t"+"a"+"\t"+"b"+"\t"+"c"+"\t"+"d");
for(int i = 0;i < 4;i++){
char startNode = (char) ('a' + i);
System.out.print(startNode+"\t");
for(int j = 0;j < 4;j++)
System.out.print(chart[i][j]+"\t");
System.out.println();
}
/*path数组中,0表示两顶点相通,1表示两顶点间有一个中间节点a,2表示 两顶点间有一个中间节点b,3两顶点间有一个中间节点c,4两顶点间有一个中间节点d.
* 100表示两顶点不相通*/
int[][] path = {{0,100,0,100},{0,0,100,100},{100,0,0,0},{0,100,100,0}};
getShortestPath(chart,path);
System.out.println("有向图chart的距离矩阵为:");
System.out.println("\t"+"a"+"\t"+"b"+"\t"+"c"+"\t"+"d");
for(int i = 0;i < 4;i++){
char startNode = (char) ('a' + i);
System.out.print(startNode+"\t");
for(int j = 0;j < 4;j++)
System.out.print(chart[i][j]+"\t");
System.out.println();
}
System.out.println("有向图chart的中间节点路径矩阵为(PS:值为0表示两节点直接相通,值为1表示两节点有一个中间节点a,值为2表示中间节点为b,依次类推):");
System.out.println("\t"+"a"+"\t"+"b"+"\t"+"c"+"\t"+"d");
for(int i = 0;i < 4;i++){
char startNode = (char) ('a' + i);
System.out.print(startNode+"\t");
for(int j = 0;j < 4;j++)
System.out.print(path[i][j]+"\t");
System.out.println();
}
System.out.println("最终求取结果为:");
printShortestPath(path,chart);
}
}
有向图chart的权重矩阵为(PS:其中值为100表示无穷大,即无法相通的路径):
a b c d
a 0 100 3 100
b 2 0 100 100
c 100 7 0 1
d 6 100 100 0
有向图chart的距离矩阵为:
a b c d
a 0 10 3 4
b 2 0 5 6
c 7 7 0 1
d 6 16 9 0
有向图chart的中间节点路径矩阵为(PS:值为0表示两节点直接相通,值为1表示两节点有一个中间节点a,值为2表示中间节点为b,依次类推):
a b c d
a 0 3 0 3
b 0 0 1 3
c 4 0 0 0
d 0 3 1 0
最终求取结果为:
a——>a最短路径为:a->a 。 路径长度为:0
a——>b最短路径为:a->c , c->b 。 路径长度为:10
a——>c最短路径为:a->c 。 路径长度为:3
a——>d最短路径为:a->c , c->d 。 路径长度为:4
b——>a最短路径为:b->a 。 路径长度为:2
b——>b最短路径为:b->b 。 路径长度为:0
b——>c最短路径为:b->a , a->c 。 路径长度为:5
b——>d最短路径为:b->a , a->c , c->d 。 路径长度为:6
c——>a最短路径为:c->d , d->a 。 路径长度为:7
c——>b最短路径为:c->b 。 路径长度为:7
c——>c最短路径为:c->c 。 路径长度为:0
c——>d最短路径为:c->d 。 路径长度为:1
d——>a最短路径为:d->a 。 路径长度为:6
d——>b最短路径为:d->a , a->c , c->b 。 路径长度为:16
d——>c最短路径为:d->a , a->c 。 路径长度为:9
d——>d最短路径为:d->d 。 路径长度为:0
Java动态规划实现最短路径问题的更多相关文章
- java动态规划取硬币问题
最近一直在研究动态规划的问题.今天遇到了取硬币问题. 其实动态规划还是,我从底部向顶部,依次求出每个状态的最小值,然后就可以标记上. 这道题目就是,假如有1,5,7,10这四种币值的硬币,我取14元, ...
- java动态规划问题
这里是简单的动态规划问题.其实,如果我们学过数据结构,应该就接触过动态规划问题,当时一直没有反应过来.我们求最小生成树用的是贪婪算法.而求最短路径就是动态规划.从一个点出发,到另外每个点的最短距离.在 ...
- Java动态规划
1. 介绍 动态规划典型的被用于优化递归算法,因为它们倾向于以指数的方式进行扩展.动态规划主要思想是将复杂问题(带有许多递归调用)分解为更小的子问题,然后将它们保存到内存中,这样我们就不必在每次使用它 ...
- java 动态规划解决最大连续子数列和
很多动态规划算法非常像数学中的递推.我们如果能找到一个合适的递推公式,就能很容易的解决问题.我们用dp[n]表示以第n个数结尾的最大连续子序列的和,这里第n个数必须在子序列中.于是存在以下递推公式: ...
- java动态规划导弹问题
这是一道动态规划题,和昨天的取硬币还有最长公共字串有点类似. 1.题目描述: 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一 ...
- 划分问题(Java 动态规划)
Description 给定一个正整数的集合A={a1,a2,-.,an},是否可以将其分割成两个子集合,使两个子集合的数加起来的和相等.例A = { 1, 3, 8, 4, 10} 可以分割:{1, ...
- 算法:矩阵连乘(Java)动态规划
Description 给你2个矩阵A.B,我们使用标准的矩阵相乘定义C=AB如下: A数组中栏(column)的数目一定要等于B数组中列(row)的数目才可以做此2数组的相乘.若我们以rows(A) ...
- java 动态规划解决上楼梯问题
问题描述: 你正在爬楼梯. 它需要n步才能达到顶峰. 每次你可以爬1或2步. 您可以通过多少不同的方式登顶? 注意:给定n将是一个正整数. Example 1: Input: 2 Output: 2 ...
- [leetcode] 45. 跳跃游戏 II(Java)(动态规划)
45. 跳跃游戏 II 动态规划 此题可以倒着想. 看示例: [2,3,1,1,4] 我们从后往前推,对于第4个数1,跳一次 对于第3个数1,显然只能跳到第4个数上,那么从第3个数开始跳到最后需要两次 ...
随机推荐
- [hdu5521 Meeting]最短路
题意:有N个点,给定M个集合,集合Si里面的点两两之间的距离都为Ti,集合里面的所有点数之和<=1e6.有两个人分别在1和N处,求1个点使得两个人到这一点距离的最大值最小 思路:这题是裸的最短路 ...
- 业务系统请求zabbix图表性能调优
性能调优实践 性能调优实践 背景 问题分析 后端优化排查 前端优化排查 后端长响应排查 zabbix server 优化 总结 背景 用 vue.js 的框架 ant-design vue pro 实 ...
- 关于oracle怎么看清楚字段的一些实践
在oracle存储过程或者平时编码中会有很多时候对不上字段,这时候在字段逗号后面可以主动加上--数字. 还有的是应该注意尽量让每个字段都占有一行的空间.下面部分截图说明
- 帝国cms 批量删除包含关键字的 内容
删除包含关键字的 内容delete from www_kaifatu_com_ecms_news where playurl like '%关键字%'
- C#实现局域网聊天 通讯 Socket TCP 多人
程序分别为服务端与客户端,服务端创建套接字使用多线程侦听多客户端请求 代码需要引用System.Net:和System.Net.Socket:这两个类 分享源码demo:https://pan.bai ...
- VS2019 使用
下载 官网下载:链接 安装 1.点击下载程序,会显示这个界面 2.点击“继续”,等待安装程序安装完成 4.安装程序下载安装验证完毕,将会提示进入这个界面 5.为了方便起见,这里仅展示安装C++功能,在 ...
- 案例(一) 利用机器算法RFM模型做用户价值分析
一.案例背景 在产品迭代过程中,通常需要根据用户的属性进行归类,也就是通过分析数据,对用户进行归类,以便于在推送及转化过程中获得更大的收益. 本案例是基于某互联网公司的实际用户购票数据为研究对象, ...
- React学习随笔
一.在非create-react-app创建的项目,使用JSX需要注意的问题 1.1 入门的时候,要引入Babel,并将<script>标签加上type='text/babel'的属性. ...
- 移除项目中的UIWebView
1,AFN升级4.0 2,代码中搜索UIWebView移除相关文件 3,检查库是否使用的UIWebView 参考 https://www.jianshu.com/p/3a645500d461
- 环境篇:Zeppelin
环境篇:Zeppelin Zeppelin 是什么 Apache Zeppelin 是一个让交互式数据分析变得可行的基于网页的开源框架.Zeppelin提供了数据分析.数据可视化等功能. Zeppel ...