图论算法笔记

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 第12章 最短路径算法
    • 12-1 有权图的最短路径问题
      • 最短路径问题-路径规划
        • 单源最短路径
        • 带权图的最短路径和无权图的最短路径
        • 带权图的最短路径算法-Dijkstra算法
    • 12-2 Dijkstra 算法的原理和模拟
    • 12-3 实现 Dijkstra 算法
    • 12-4 Dijkstra 算法的优化
    • 12-5 更多关于 Dijkstra 算法的讨论
    • 12-7 Bellman-Ford 算法


第12章 最短路径算法

12-1 有权图的最短路径问题

最短路径问题-路径规划

单源最短路径

可以通过广度有限算法或Dijkstra算法,而非深度优先搜索算法

深度优先搜索算法在遍历图时会沿着一个路径一直往下探索,直到无法再继续下去才回溯。这种算法适用于寻找图中的某个目标节点,但不适合求解最短路径问题。因为深度优先搜索算法无法保证找到的路径是最短路径,它可能会陷入一个较长的路径中而错过更短的路径。

相比之下,广度优先搜索算法和迪杰斯特拉算法都可以用于求解单源最短路径问题。广度优先搜索算法通过逐层扩展搜索的方式,从起始节点开始向外层扩展,直到找到目标节点或者遍历完整个图。迪杰斯特拉算法则是一种贪心算法,通过不断更新起始节点到其他节点的最短距离,逐步确定最短路径。

总的来说,如果图中没有边权重(即每条边的权重都相同),那么广度优先搜索算法是一个简单且有效的解决方案。如果图中存在边权重,那么迪杰斯特拉算法是更常用的选择,它可以处理带权重的图,并找到最短路径。

求解到从源点s到图中任意点的最短路径,如果找到了某条路径,那么程序结束。

带权图的最短路径和无权图的最短路径

无权图的最短路径的寻路只需要找到路径数最少的就是解,但是带权图不同

带权图的最短路径算法-Dijkstra算法

Dijkstra算法不能处理负权边
如果要处理负权边,要用其他算法,会使复杂度变高

12-2 Dijkstra 算法的原理和模拟

路径图

初始化

dis01234

以0为源点,0-0的距离为0,是确定的,用加粗斜体表示,同时由于0-2的距离是所有距离中最小的,也即,即使从0到1然后绕路到2,也无法更小,所以,0-2的距离为2,也是确定的。注意,这里没有负权边。

dis01234
042

从2开始可以访问1、3、4,可以更新0到这三个点的距离,同样的道理,0-1的距离被确定了。

dis01234
03267

从1出发,访问3、4,可以更新,并确定0-3的距离是5

dis01234
03256

最后从3访问4,发现距离还是6,确定0-4距离为6。

dis01234
03256

Dijkstra 算法:设置起始源点,将其到自身的距离设为0,然后循环
每轮循环:

  1. 找到当前没有访问的最短路节点
  2. 确认这个节点的最段路就是当前大小(注意没有负权边)
  3. 根据这个节点的最短路大小,更新其他节点的路径长度

图示:
Dijkstra 算法图示

12-3 实现 Dijkstra 算法

以下是使用Go语言实现Dijkstra算法的示例代码:

package mainimport ("fmt""math"
)type Graph struct {nodes []stringedges map[string]map[string]int
}func NewGraph() *Graph {return &Graph{nodes: []string{},edges: make(map[string]map[string]int),}
}func (g *Graph) AddNode(node string) {g.nodes = append(g.nodes, node)
}func (g *Graph) AddEdge(src, dest string, weight int) {if _, ok := g.edges[src]; !ok {g.edges[src] = make(map[string]int)}g.edges[src][dest] = weight
}func Dijkstra(graph *Graph, start string) map[string]int {distances := make(map[string]int) // distances用于存储从起始节点到各个节点的当前最短距离,visited := make(map[string]bool)  // visited用于记录已经访问过的节点。for _, node := range graph.nodes {distances[node] = math.MaxInt32 //循环遍历所有节点,并将其初始距离设置为无穷大(math.MaxInt32),}distances[start] = 0 // 除了起始节点的距离设置为0。for i := 0; i < len(graph.nodes); i++ {current := minDistance(distances, visited) // 选择当前未访问的最短距离的节点作为当前节点,visited[current] = true                    // 并将其标记为已访问。// 遍历当前节点的邻居节点,并更新它们的最短距离。如果通过当前节点到达邻居节点的路径比已知的最短距离更短,则更新邻居节点的最短距离。for neighbor, weight := range graph.edges[current] {if !visited[neighbor] && distances[current]+weight < distances[neighbor] {distances[neighbor] = distances[current] + weight}}}return distances
}func minDistance(distances map[string]int, visited map[string]bool) string {min := math.MaxInt32var minNode stringfor node, distance := range distances {if !visited[node] && distance < min {min = distanceminNode = node}}return minNode
}func main() {graph := NewGraph()graph.AddNode("A")graph.AddNode("B")graph.AddNode("C")graph.AddNode("D")graph.AddNode("E")graph.AddEdge("A", "B", 4)graph.AddEdge("A", "C", 2)graph.AddEdge("B", "C", 1)graph.AddEdge("B", "D", 5)graph.AddEdge("C", "D", 8)graph.AddEdge("C", "E", 10)graph.AddEdge("D", "E", 2)distances := Dijkstra(graph, "A")fmt.Println("Shortest distances from node A:")for node, distance := range distances {fmt.Printf("Node: %s, Distance: %d\n", node, distance)}
}

这个示例代码创建了一个Graph结构体来表示图,其中包含节点和边的信息。然后,通过AddNode和AddEdge方法添加节点和边的权重。最后,调用Dijkstra函数传入图和起始节点来计算最短路径。

在Dijkstra函数中,首先初始化距离数组distances和访问标记visited。然后,使用循环选择当前未访问的最短路径节点,并更新与其相邻节点的距离。最后,返回最短路径距离的映射。

运行上述代码将输出从节点A开始的最短距离结果。

12-4 Dijkstra 算法的优化

12-5 更多关于 Dijkstra 算法的讨论

如果只考虑两个点,那么只要确定了两点的最短路径就可以停止了。

12-7 Bellman-Ford 算法

用于处理有负权边的情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/143.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

搭载率突破40%!智能数字座舱比拼,车企还有降本空间吗?

进入2023年&#xff0c;汽车行业的「降本」风潮&#xff0c;驱动产业链上下游开始思考智能化、电动化的投入产出。除了显性的硬件成本&#xff08;继续堆料&#xff0c;强调性价比&#xff0c;还是减配&#xff09;&#xff0c;软件及背后的开发成本&#xff0c;对于车企来说&a…

GitLab 入选 Forrester Wave™️ 集成软件交付平台,并获评唯一「领导者」!

越来越多企业意识到多工具链集成带来的低效和高成本问题&#xff0c;同时承受着可见性低、反馈不畅通、网络风险大等痛点&#xff0c;应用平台方法来交付软件的呼声越来越大。 极狐(GitLab) 很早就意识到了平台方法的价值&#xff0c;也坚信极狐GitLab 这种单一应用程序的 DevS…

学习vue2笔记

学习vue2笔记 文章目录 学习vue2笔记脚手架文件结构关于不同版本的Vuevue.config.js配置文件ref属性props配置项mixin(混入)插件scoped样式总结TodoList案例webStorage组件的自定义事件全局事件总线&#xff08;GlobalEventBus&#xff09;消息订阅与发布&#xff08;pubsub&am…

el-date-picker 日期时间进行限制,精确到时分秒

需求&#xff1a;用户只能选择当时时间或当前时间之前的时间&#xff0c;且精确到时分秒 实现效果&#xff1a;用户只能选择当前时间的时间&#xff0c;如果选择是当天之前的时间&#xff0c;时分秒不做限制&#xff0c;如果选择的是当天时间&#xff0c;就要判断时分秒&#…

【数据挖掘】时间序列教程【十】

5.4 通用卡尔曼滤波 上一节中描述的状态空间模型作为观测方程的更一般的公式 和状态方程 这里是一个p1 向量是一个k1 向量, 是一个pk 矩阵, 是kk 矩阵。我们可以想到的和 给定初始状态 和 &#xff0c;预测方程为&#xff08;类似于上面&#xff09; 并且更新方程是&#x…

华为Harmony应用开发初探

HarmonyOS是一款面向万物互联时代的、全新的分布式操作系统。在传统的单设备系统能力基础上,HarmonyOS提出了基于同一套系统能力、适配多种终端形态的分布式理念,能够支持手机、平板、智能穿戴、智慧屏、车机等多种终端设备,提供全场景(移动办公、运动健康、社交通信、媒体…

外包干了2个月,技术退步明显...

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

Linux进程(二)---进程的优先级和环境变量

我想在这先完成上一章的一个未说完的话题.最后一个我们讲到了僵尸进程&#xff0c;是指子进程已经结束&#xff0c;但是父进程还在运行没有来得及回收.此时这个子进程便是僵尸进程. 但是如果父进程运行完了&#xff0c;也没有回收就直接结束了&#xff0c;那这个子进程改由谁维…

用html+javascript打造公文一键排版系统3:获取参数设置、公文标题排版

我们用自定义函数setDocFmt()来实现对公文的排版。 一、获取公文参数值 要对公文进行排版&#xff0c;首先要读取公文“参数设置”区中的参数值。比如公文要求对公文标题的一般规定是&#xff1a;一般用2号小标宋体字&#xff0c;居中显示。标题与正文中间空一行。 这些是“参…

Python控制流程盘点及高级用法、神秘技巧大揭秘!

目录 一、条件语句&#xff08;If-Elif-Else&#xff09; 二、循环结构&#xff08;For和While&#xff09; 三、异常处理&#xff08;Try-Except&#xff09; 四、控制流程的高级用法&#xff01; 1. 列表解析 2. 生成器表达式 3. 装饰器 One More Thing&#xff01;&…

Microsoft 宣布今年底关闭开源软件托管平台 CodePlex

Microsoft 宣布&#xff0c;将关闭开源软件托管平台 CodePlex。Microsoft 2006 年推出这项服务&#xff0c;并决定在今年 12 月 15 日将其关闭。 Microsoft 公司副总裁 Brian Harry 在网上博客中写道&#xff0c;人们将可以下载他们的数据档案&#xff0c;Microsoft 正与面向开…

配电柜实时监测?这也太会省力了吧!

现代企业厂房的安全和效率对于业务的成功至关重要。在这个背景下&#xff0c;配电柜监控成为了一项关键的技术。通过实时监测和管理厂房内的配电柜&#xff0c;企业可以确保电力供应的稳定性&#xff0c;提高能源利用效率&#xff0c;并及时发现和解决潜在的故障和安全风险。 配…

matlab学习指南(2):安装工具箱Toolbox的方法(详细图解)

&#x1f305;*&#x1f539;** φ(゜▽゜*)♪ **&#x1f539;*&#x1f305; 欢迎来到馒头侠的博客&#xff0c;该类目主要讲数学建模的知识&#xff0c;大家一起学习&#xff0c;联系最后的横幅&#xff01; 喜欢的朋友可以关注下&#xff0c;私信下次更新不迷路&#xff0…

Uniapp 版本更新

文章目录 前言Uniapp更新确定接口是否能够使用基本代码封装更新软件区别 前言 软件发布之后更新是经常出现的需求。我们希望软件能够自动连网更新软件&#xff0c;而不是重新去手动安装一个apk安装包。不需要更新的软件只有两个&#xff0c;一个是微信小程序&#xff0c;另一个…

openpnp - 汇川 Inovance IS620PS2R8I-IAB-C的参数读取

文章目录 openpnp - 汇川 Inovance IS620PS2R8I-IAB-C的参数读取概述笔记伺服和配套电机型号官方伺服调试软件笔记H00H01H02H03H04H05H06H07H08H09H0AH0BH0CH0DH0FH11H12H16H17H30H31自定义组备注END openpnp - 汇川 Inovance IS620PS2R8I-IAB-C的参数读取 概述 设备中用到了…

学习笔记——vscode界面设置界面缩放级别

使用vscode时&#xff0c;不知道按了什么快捷键&#xff0c;vscode窗口缩放了。 调整方法&#xff1a;设置 > 窗口(window) > Zoom Level

淘宝订单拉取更新历史状态~需求

&#x1f4da;目录 订单接口api需求问题解决 Map<String,TaobaoOrder> 订单接口api 可自行查询官网文档&#xff0c;点击进入 需求 通过接口中has_next 标识判断该时间断是否还有下一页数据,直到该值数据为false时,表面该时间范围内的订单数据获取完成. 拉取完成后需要对…

初阶C语言——指针

Hello&#xff0c;我们又见面了&#xff0c;时间过的好快啊&#xff0c;转眼间也已经写了这么多份博客了&#xff0c;在接下来的一年里&#xff0c;小编也会认真学习的敲代码&#xff0c;我们一起进步&#xff0c;那今天开始讲我们的指针&#xff0c;指针这一章节在C语言的学习…

【K8S系列】深入解析K8S监控

序言 做一件事并不难&#xff0c;难的是在于坚持。坚持一下也不难&#xff0c;难的是坚持到底。 文章标记颜色说明&#xff1a; 黄色&#xff1a;重要标题红色&#xff1a;用来标记结论绿色&#xff1a;用来标记论点蓝色&#xff1a;用来标记论点 Kubernetes (k8s) 是一个容器编…

微服务实例构建成 docker 镜像实例

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…