- 浏览: 122861 次
- 性别:
- 来自: 上海
最新评论
这里使用的是Dijkstra来计算最短路径。事实上Dijkstra完成时,指定节点到所有节点的最小路径均已求出。
算法简述如下:
准备好两个辅助性数据结构:
1 ParentLength : 用来记录到当前节点之前的父节点,与到当前节点的最小路径
2 Path: 记录指定节点到所有节点的ParentLength。初始化时,所有的ParentLength的父节点都为指定的起始节点,长度都是INFINITY,代表没有联通,距离无穷大。
Path的关键算法是adjust(from,to,length),每当发现一条新的,从一个已访问的节点(from)到未访问的节点(to)之间的新路径时,Path则用其更新ParentLength列表,重新计算到那个未访问节点(to)的最新距离:以前到from节点的距离+新的距离,然后比较它与to节点对应的ParentLength老的距离之间的长度,如果新距离短,则将to节点对应的ParentLength更新为长度为新距离的,父节点为from;以此步骤保证Path总是保持当前遍历状态下,到各个节点的最短路径。
Path的另一个关键算法是getMin,它会返回到所有未访问节点中,最短的路径的那个节点。
图使用邻接矩阵法表示,关于邻接矩阵可参见:Graph 图-邻接表法
Graph.path是最小路径算法,工作方式如下:
根据指定的起始节点初始化返回值Path对象。
将指定的起始节点标志为已访问。并设置为当前节点。
然后
1 找到当前节点所有联通的未知节点,和到这些路径长度,调用Path.adjust更新Path。
2 步骤 1 结束后,从调用Path.getMin获得到所有未访问节点中,最短的路径的那个节点。标志为访问过,并作为当前节点。
3 重复 步骤 1 步骤 2 n次(n为图中的节点数量),算法结束。
代码中的Path.print()为打印函数,为测试之用。
Path.main()提供简单测试。
class ParentLength { //记载上一个节点与当前最小路径 private int parent; //上一个节点 private int length; //最小路径长度 ParentLength(int parent, int length) { this.parent = parent; this.length = length; } int parent() { return parent; } int length() { return length; } } class Path { //存储最小路径 private ParentLength[] pls; private Graph g; //确定指定位置的节点是否被访问过和打印时使用 Path(int size, int start, Graph g) { //初始化最小路径数组,将所有最小路径的起点都置为start,并将路径长度置为INFINITY pls = new ParentLength[size]; for(int i=0; i<size; i++) pls[i] = new ParentLength(start,Graph.INFINITY); this.g = g; } //根据新发现的路径调整最小路径 void adjust(int from, int to, int length) { //根据上一个节点的路径,计算出新的路径长度 int newLength = pls[from].length() != Graph.INFINITY? pls[from].length() + length: length; //如果到指定节点的新路径长度小于原来的最小路径,则更新到该节点的最小路径,和其父节点 if(newLength < pls[to].length()) pls[to] = new ParentLength(from,newLength); } int getMin() { //求得到当前所有未访问节点的最近的一个节点 int pos = 0; for(int i=1; i<pls.length; i++) if(!g.isVisited(i) && pls[i].length() < pls[pos].length()) pos = i; return pos; } void print() { //打印 for(int i=0; i<pls.length; i++) { int current = i; System.out.print((pls[current].length() == Graph.INFINITY? "INFINITY": pls[current].length()) + " " ); do { System.out.print(g.get(current) + " <-- "); current = pls[current].parent(); } while(current != pls[current].parent()); System.out.println(g.get(current)); } } } class Vertex { //顶点,记载数据value,并记载是否访问过 private Object value; private boolean isVisited; Vertex(Object value) { this.value = value; } void visit() { isVisited = true; } void clean() { isVisited = false; } boolean isVisited() { return isVisited; } Object value() { return value; } @Override public String toString() { return "" + value; } } class Graph { private Vertex[] vertexs; private int[][] adjMat; private int length = 0; static final int INFINITY = ~(1<<31); //整数的最大值,表示没有路径 Graph(int size) { //初始化 vertexs = new Vertex[size]; adjMat = new int[size][size]; for(int i=0; i<size; i++) //将邻接矩阵初始化为全部不通 for(int j=0; j<size; j++) adjMat[i][j] = INFINITY; } void add(Object value) { //添加顶点 assert length <= vertexs.length; vertexs[length++] = new Vertex(value); } void connect(int from, int to, int length) { adjMat[from][to] = length; //设置指定节点之间的有向路径 } /** * 在邻接矩阵中,查找指定顶点的未访问过邻居顶点 * 如果从从起点到终点的边存在,且没有标志为访问,则返回终点下标。 * @param offset 指定开始查找的列 * @param index 指定查找的行 */ int findNeighbor(int index,int offset) { for(int i=offset; i<length; i++) { if(adjMat[index][i] != INFINITY && !vertexs[i].isVisited()) return i; } return -1; } Vertex get(int index) { return vertexs[index]; } Path path(int index) { //最小路径算法 assert vertexs[index] != null; Path result = new Path(length,index,this); //初始化Path vertexs[index].visit(); //将其实节点标志为访问过 for(int n=1; n<length; n++) { //一共经过n此迭代就可得到最终结果 int i = 0; while((i = findNeighbor(index,i+1)) != -1) //寻找当前节点的所有为访问邻居 result.adjust(index, i, adjMat[index][i]); //根据新路线调整最小路径 index = result.getMin(); //将当前节点更新为路径表中为访问的最近的那个节点 vertexs[index].visit(); //将当前节点标志为访问过; } clean(); return result; } boolean isVisited(int index) { return vertexs[index].isVisited(); } void clean() { for(Vertex v: vertexs) if(v != null)v.clean(); } public static void main(String[] args) { Graph g = new Graph(20); //添加节点 g.add('a'); g.add('b'); g.add('c'); g.add('d'); g.add('e'); //添加有向有权边 g.connect(0,1,50); g.connect(0,3,80); g.connect(1,2,60); g.connect(1,3,90); g.connect(2,4,40); g.connect(3,2,20); g.connect(3,4,70); g.connect(4,1,50); Path p = g.path(0); //获得最小路径 p.print(); //打印 } }
评论
This blog is the best one in javaeye, keep update please.
发表评论
-
图-代权最小树
2008-05-27 00:07 2316图中代权的最小树的问 ... -
图-每一对端点间的最小距离
2008-05-26 00:24 2192与传递闭包问题 非常相似的一个问题是,能不能给出一个矩阵,根据 ... -
图-传递闭包
2008-05-23 07:57 4862图的传递闭包是指修正后的邻接矩阵表示的图。(见Graph 图- ... -
图-拓扑排序
2008-05-22 00:54 2666当每个任务有前后置关系时,需要找到一种满足前后置关系的路线,将 ... -
图-最小树
2008-05-21 00:08 1899如果一个图中所有点都是联通的,求最小树可以将图遍历完成,这里的 ... -
图-广度优先遍历
2008-05-20 00:11 4317这里的图的广度优先遍历算法利用了队来实现。 图的深度遍历原则: ... -
图-深度优先遍历
2008-05-19 00:14 4520这里的图的深度优先算法利用了栈来实现。 图的深度遍历原则: 1 ... -
递归-全排列
2008-05-16 21:00 4189将指定数组全排列打印,此处使用递归算法。 其核心是,轮流将数组 ... -
递归-组合
2008-05-15 01:12 2667求指定数据的组合,这里的指定数据用一个数组模拟所有可以选择的数 ... -
递归-背包问题
2008-05-14 00:10 4821背包问题有许多种形式,最简单的背包问题形式:现在有一堆石头,( ... -
递归-汉诺塔
2008-05-13 00:13 1878汉诺塔问题。 这里顺便可以求出一共需要搬运的次数。 以下是汉诺 ... -
递归-求幂
2008-05-12 00:08 3039计算幂,n^m,其中n为底数,m为幂 当m取值比较大时如果采用 ... -
递归-二分法查找
2008-05-11 02:03 3927二分法查找是建立在针对有序数组的查找,这里使用的是递归的算法, ... -
递归-阶乘
2008-05-10 15:45 1979用递归算法求得阶乘。 阶乘用迭代可以更有效的求得。这里只是演示 ... -
排序-堆
2008-05-08 08:34 1756堆排序的时间效率与快速排序 相同,也为O(n * log n) ... -
排序-基数
2008-05-07 00:24 1282基数排序是种与众不同的排序方法,它不是基于比较和交换。其理论时 ... -
排序-快速
2008-05-06 00:39 1460快速排序是通用排序中 ... -
排序-希尔
2008-05-05 00:17 1639插入排序 对基本有序的数组效果非常好,但是对于通常情况则表现一 ... -
排序-归并
2008-05-03 17:57 1654归并排序的时间效率为O(n * log n) 算法假设两个已有 ... -
排序-插入
2008-05-02 23:30 1481插入排序算法比冒泡 和选择 略微复杂些,但效率好些。 插入排序 ...
相关推荐
Python课程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。
Python课程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。
杂货产品检测43-YOLO(v5至v9)、CreateML、Paligemma、TFRecord、VOC数据集合集.rarIPCV分配-V6 2024-01-21 6:10 PM ============================= *与您的团队在计算机视觉项目上合作 *收集和组织图像 *了解和搜索非结构化图像数据 *注释,创建数据集 *导出,训练和部署计算机视觉模型 *使用主动学习随着时间的推移改善数据集 对于最先进的计算机视觉培训笔记本,您可以与此数据集一起使用 该数据集包括7012张图像。 家庭废物以createMl格式注释。 将以下预处理应用于每个图像: *像素数据的自动取向(带有Exif-Arientation剥离) *调整大小为640x640(拉伸) 没有应用图像增强技术。
Android 毕业设计,Android 毕业设计,小Android 程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、本项目仅用作交流学习参考,请切勿用于商业用途。
谁喜欢谁下载,没啥商业价值,comsol也能做,不过我这产量更大
Python课程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。
Android 毕业设计,Android 毕业设计,小Android 程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。
推箱子Python小游戏
该新媒体视域下的中国古诗词展演主要为管理员和用户两类用户角色提供需求,管理员在后台可以对系统进行全面管理,用户在前台可以进行查看系统信息,注册登录,查询校园失物,评论,下载校园失物等操作。 项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 部署容器:tomcat7
内容概要:本文介绍了使用MATLAB实现PSO-BiLSTM-Attention粒子群优化双向长短期记忆神经网络融合注意力机制的多特征分类预测模型。通过PSO优化BiLSTM模型的超参数、引入注意力机制增强模型的特征提取能力,提升了多维度数据的分类精度。模型在金融风险预测、医疗健康预测、交通流量预测等多个领域具有广泛的应用前景。项目详细描述了模型架构、代码实现、训练与优化、模型评估与可视化、以及GUI界面设计等方面的内容。 适合人群:具备一定编程基础,工作1-3年的数据科学家和机器学习工程师。 使用场景及目标:① 金融、医疗、交通等领域的多特征分类预测任务;② 结合PSO优化BiLSTM超参数、引入注意力机制,提升模型预测准确度。 阅读建议:本文详细讲解了模型的理论背景、算法实现和应用案例,适合希望深入理解深度学习和优化算法的读者。建议结合代码和实际数据进行实验,以便更好地掌握模型的设计和优化过程。
Java项目-基于SSM的物资管理系统项目源码
Video_2024-12-18_000023.wmv
Python课程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。
系统实现: 用户功能模块:用户点击进入到系统操作界面,可以对主页、个人中心、我的收藏管理、订单管理等功能模块,我的收藏管理:通过列表可以获取用户ID、收藏ID、表名、收藏名称、收藏图片信息并进行修改操作 管理员功能模块:管理员通过用户名和密码填写完成后进行登录。管理员登录成功后进入到系统操作界面,可以对主页、个人中心、用户管理、商品分类管理、商品信息管理、系统管理、订单管理等功能模块进行相对应操作。 项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 服务器:tomcat7
1、嵌入式物联网单片机项目开发实战。例程经过精心编写,简单好用。 2、代码使用KEIL 标准库开发,当前在STM32F103运行,如果是STM32F103其他型号芯片,依然适用,请自行更改KEIL芯片型号以及FLASH容量即可。 3、软件下载时,请注意keil选择项是jlink还是stlink。 4、有偿指导v:wulianjishu666; 5、如果接入其他传感器,请查看发布的其他资料。 6、单片机与模块的接线,在代码当中均有定义,请自行对照。 7、若硬件差异,请根据自身情况调整代码,程序仅供参考学习。 8、代码有注释说明,请耐心阅读。
项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 部署容器:tomcat7
Java项目-基于SSM的网上淘书吧
内容概要:本文详细介绍了 Oracle 19c 中的闪回技术,包括闪回查询、闪回事务查询、闪回丢弃、闪回表、闪回数据库和闪回归档。具体讲解了每种闪回技术的原理、配置方法、操作步骤和限制条件,并提供了具体的实例和 SQL 命令。目的是帮助数据库管理员和开发人员理解和掌握如何利用这些技术来提高数据恢复和错误修复的能力,减少数据库管理的复杂性和风险。 适合人群:Oracle 数据库管理员、数据库开发人员及维护人员。 使用场景及目标:① 使用闪回技术快速恢复因误操作或其他错误导致的数据丢失;② 配置闪回技术以实现高效的数据库恢复;③ 在日常运维中监控和管理闪回操作。 其他说明:本文不仅提供了理论上的解释,还包含了实际操作的示例,以便读者能够更好地理解和应用这些技术。