图论算法笔记

news2024/11/27 4:26:23

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

文章目录

  • 第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 main

import (
	"fmt"
	"math"
)

type Graph struct {
	nodes []string
	edges 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.MaxInt32
	var minNode string

	for node, distance := range distances {
		if !visited[node] && distance < min {
			min = distance
			minNode = 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.coloradmin.cn/o/753366.html

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

相关文章

检测到目标Strict-Transport-Security响应头缺失

详细描述 Web 服务器对于 HTTP 请求的响应头中缺少 Strict-Transport-Security&#xff0c;这将导致浏览器提供的安全特性失效。 当 Web 服务器的 HTTP 头中包含 Strict-Transport-Security 头时&#xff0c;浏览器将持续使用 HTTPS 来访问 Web 站点&#xff0c;可以用来对抗协…

Echart柱形图条纹设置

代码内容: option {xAxis: {type: category,data: [Mon, Tue, Wed, Thu, Fri, Sat, Sun]},yAxis: {type: value},series: [{data: [120, 200, 150, 80, 70, 110, 130],type: bar},{data: [20, 40, 90, 40, 30, 70, 120],type: bar},{data: [140, 230, 120, 50, 30, 150, 120]…

利用远程调试获取Chromium内核浏览器Cookie

前言 本文将介绍不依靠DPAPI的方式获取Chromium内核浏览器Cookie 远程调试 首先我们以edge为例。edge浏览器是基于Chromium的&#xff0c;而Chromium是可以开启远程调试的&#xff0c;开启远程调试的官方文档如下&#xff1a; https://blog.chromium.org/2011/05/remote-deb…

8.带你入门matlab 数据统计与分析——区间参数估计 均匀分布(matlab 程序 )

1.简述 本文将涉及到数理统计的最后一个模块——参数估计&#xff0c;后续将更新的模块是多项式计算、数据插值和曲线拟合。 在讲述使用matlab来实现参数估计之前&#xff0c;有必要去了解一些基本原理。 1.离散型随机变量的极大似然估计法: (1) 似然函数 若X为离散型, 似然函数…

NFTScan 与 Decert 达成合作伙伴,双方在 NFT 数据方面展开合作

近日&#xff0c;NFT 数据基础设施 NFTScan 与 Decert 达成合作伙伴关系&#xff0c;双方在多链 NFT 数据层面展开合作。在 Decert 产品中&#xff0c;由 NFTScan 为其提供专业的多链 NFT 数据支持&#xff0c;为用户带来优质的 NFT 搜索查询等相关交互功能&#xff0c;提升用户…

SQL 上升的温度

197 上升的温度 SQL架构 表&#xff1a; Weather ---------------------- | Column Name | Type | ---------------------- | id | int | | recordDate | date | | temperature | int | ---------------------- id 是这个表的主键 该表包含特定日期的温度信息 编写一个 SQL …

MySQL主从复制(一主一从)

文章目录 MySQL主从复制(一主一从)什么是主从复制主从复制的原理主从复制的优点准备工作配置主数据库Master配置从数据库Slave测试 MySQL主从复制(一主一从) 什么是主从复制 MySQL主从复制是指数据可以从一个MySQL数据库服务器的主节点复制到一个或多个从节点。主节点记录了所…

CAP原则的一致性、可用性、分区容错性

2000年&#xff0c;Eric Brewer在ACM PODC分布式计算原理专题讨论会上首次提出CAP原则。后来&#xff0c;麻省理工学院的两位科学家(赛斯吉尔伯特和南希林奇)证明了CAP原则的正确性。目前&#xff0c;CAP原则被大型公司广泛采纳&#xff0c;例如Amazon公司。 CAP原则又称CAP定…

Unity Obfuscator

官方仓库 学习日期&#xff1a;2023-07-13&#xff08;防止后续仓库特性或功能更新无对比时间&#xff09; 目标&#xff1a;本文介绍使用此github库&#xff0c;混淆unity项目的代码&#xff0c;在ILSpy中无法正确反编译。 一、说明 官方说明 配置界面 Features: ControlFlow…

Web 前端 Day 6

函数 <script>// parseInt(200px)// getSum(20, 30) ​ ​function sayHi() {console.log(hello,function!)} ​// 函数必须进行调用&#xff0c;才会执行sayHi()let age 21 ​// 函数要有返回值&#xff0c;一定要添加return关键字&#xff0c;否则返回值为undefinedfu…

五子棋小游戏 java版(代码+详细注释)

游戏展示 这周闲来无事&#xff0c;再来写个五子棋小游戏。基本功能都实现了&#xff0c;包括人人对战、人机对战。界面布局和功能都写的还行&#xff0c;没做到很优秀&#xff0c;但也不算差。如有需要&#xff0c;做个java初学者的课程设计或者自己写着玩玩也都是不错的&…

关于酒吧的八个大实话

1、酒吧风格定位取决于你酒吧面向的客户群体 2、酒吧要根据所在地区人流量开酒吧&#xff0c;大酒吧开在人流量少的可能死于客流量太小&#xff0c;合理的酒吧规模才能生存。3、酒吧客群不能只面向亲朋好友&#xff0c;再好的朋友也不可能天天来照顾你的生意。4、酒吧注重酒吧…

Task管理系统项目

Task管理系统项目 项目开发意义和目的 本项目所开发的系统为Task管理系统。管理信息系统是一个由人和计算机等组成的能够提供信息以支持一个组织机构内部的作业、管理、分析和决策职能的系统。管理信息系统利用计算机的硬件和软件&#xff0c;手工规程.分析、计划、控制和决策用…

浏览器视口

目录 css单位相对单位绝对单位 像素分类物理像素逻辑像素css像素 DPRPPI浏览器视口布局视口视觉视口理想视口 css单位 在css中我们会使用到许多单位&#xff0c;如px&#xff0c;em&#xff0c;rem&#xff0c;vw&#xff0c;vh等等 整体上&#xff0c;我们可以将它们分成两类…

XXE漏洞

XML基础 概述 XML是一种用于标记电子文件使其具有结构性的可扩展标记语言。 XML是一种灵活的语言&#xff0c;类似于HTML语言&#xff0c;但是并没有固定的标签&#xff0c;所有标签都可以自定义&#xff0c;其设计的宗旨是传输数据&#xff0c;而不是像HTML一样显示数据。 …

Cortex-M3与Aurix的堆栈

1. TC397是一个基于ARM Cortex-M3内核的微控制器芯片&#xff0c;其堆栈是由系统初始化代码初始化的。在ARM Cortex-M3架构中&#xff0c;堆栈通常由两个寄存器来管理&#xff1a;主堆栈指针&#xff08;MSP&#xff09;和进程堆栈指针&#xff08;PSP&#xff09;。 1.1 MSP是…

Vue-品牌列表案例

1.案例效果 2.用到的知识点 bootstrap 4.x 相关的知识点&#xff1a; 卡片&#xff08;Card&#xff09;、表单相关(Forms)、按钮(Buttons)、表格(Tables) vue指令与过滤器相关的知识点&#xff1a; 插值表达式、属性绑定、事件绑定、双向数据绑定、修饰符、条件渲染、列表…

云HIS系统使用和操作过程中的常见问题及解决方法

云HIS系统使用和操作过程中的常见问题及解决方法 一、门诊业务中遇到的问题 &#xff08;1&#xff09;门诊医生如何查询往期病人&#xff1f; 答&#xff1a;点击门诊医生站左侧患者列表&#xff0c;在弹出的页面点击已诊分页&#xff0c;在搜索框输入患者姓名&#xff0c;在…

数据库基本操作--------MySQL存储引擎

目录 一、存储引擎概念介绍 二、MySQL常用的存储引擎 1、MyISAM 2.1.1 MyISAM的特点 2.1.2 MyISAM 表支持 3 种不同的存储格式 2.1.3 MyISAM适用的生产场景 2、InnoDB 2.2.1 InnoDB特点 三、查看系统支持的存储引擎 四、查看表使用的存储引擎 方法一 五、修改存储引擎…

「网络编程」应用层协议_ HTTPS协议学习及原理理解

「前言」文章内容大致是应用层协议的HTTPS协议讲解&#xff0c;续上篇HTTP协议。 「归属专栏」网络编程 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 一、HTTPS协议介绍二、什么是"加密"三、为什么要加密四、常见的加密方式五、数据摘要 && 数据指纹六、…