回溯算法——我欲修仙(功法篇)

news2024/12/26 11:04:56

个人主页:【😊个人主页】
系列专栏:【❤️我欲修仙】

壁纸


系列文章目录

第一章 ❤️ 学习前的必知知识
第二章 ❤️ 二分查找


文章目录

  • 系列文章目录
  • 回溯算法🤔🤔🤔
  • 回溯算法一般可以解决的问题
  • 回溯算法的实现
  • 回溯算法的固定模板(回溯三部曲)
    • 回溯函数模板返回值以及参数
    • 回溯函数终止条件
    • 回溯搜索的遍历过程
  • 总结


回溯算法🤔🤔🤔

回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。用回溯算法解决问题的一般步骤为:

1、定义一个解空间,它包含问题的解。
2、利用适于搜索的方法组织解空间。
3、利用深度优先法搜索解空间。
4、利用限界函数避免移动到不可能产生解的子空间。

回溯法也可以叫做回溯搜索法,它是一种搜索的方式。
在二叉树系列中,我们提到过回溯,例如二叉树:
以为使用了递归,其实还隐藏着 回溯 (opens new window)。
 回溯是递归的副产品,只要有递归就会有回溯。
 回溯函数也就是递归函数,指的都是一个函数。

问题的解空间通常是在搜索问题的解的过程中动态产生的,这是回溯算法的一个重要特性。

在这里插入图片描述

回溯算法一般可以解决的问题

  • 组合问题:N个数里面按一定规则找出k个数的集合
  • 切割问题:一个字符串按一定规则有几种切割方式
  • 子集问题:一个N个数的集合里有多少符合条件的子集
  • 排列问题:N个数按一定规则全排列,有几种排列方式
  • 棋盘问题:N皇后,解数独等等

回溯算法的实现

使用回溯法解决问题的过程,实际上是建立一棵“状态树”的过程。例如,在解决列举集合{1,2,3}所有子集的问题中,对于每个元素,都有两种状态,取还是舍,所以构建的状态树为:

在这里插入图片描述

回溯算法的求解过程实质上是先序遍历“状态树”的过程。树中每一个叶子结点,都有可能是问题的答案。图中的状态树是满二叉树,得到的叶子结点全部都是问题的解。
在某些情况下,回溯算法解决问题的过程中创建的状态树并不都是满二叉树,因为在试探的过程中,有时会发现此种情况下,再往下进行没有意义,所以会放弃这条死路,回溯到上一步。在树中的体现,就是在树的最后一层不是满的,即不是满二叉树,需要自己判断哪些叶子结点代表的是正确的结果。

回溯算法的固定模板(回溯三部曲)

回溯函数模板返回值以及参数

在回溯算法中,习惯是为函数命名为backtracking,这个起名是随意。
回溯算法中函数返回值一般为void。
回溯算法需要的参数不像二叉树递归的时候那么容易一次性确定下来,所以一般是先写逻辑,然后需要什么参数,就填什么参数。

回溯函数伪代码如下:

void backtracking(参数)

回溯函数终止条件

既然是树形结构,那么我们在讲解二叉树的递归 (opens new window)的时候,就知道遍历树形结构一定要有终止条件。
所以回溯也有要终止条件。
什么时候达到了终止条件,树中就可以看出,一般来说搜到叶子节点了,也就找到了满足条件的一条答案,把这个答案存放起来,并结束本层递归。

所以回溯函数终止条件伪代码如下:

if (终止条件) {
    存放结果;
    return;
}

回溯搜索的遍历过程

回溯法一般是在集合中递归搜索,集合的大小构成了树的宽度,递归的深度构成的树的深度。

回溯函数遍历过程伪代码如下:
void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

}

for循环就是遍历集合区间,可以理解一个节点有多少个孩子,这个for循环就执行多少次。
函数这里自己调用自己,实现递归。
我们可以从图中看出for循环可以理解是横向遍历,backtracking(递归)就是纵向遍历,这样就把这棵树全遍历完了,一般来说,搜索叶子节点就是找的其中一个结果了。

总结

解决问题时,每进行一步,都是抱着试试看的态度,如果发现当前选择并不是最好的,或者这么走下去肯定达不到目标,立刻做回退操作重新选择。这种走不通就回退再走的方法就是回溯算法。

在这里插入图片描述

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

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

相关文章

Python语言简介

B站讲解视频:https://www.bilibili.com/video/BV1Mv4y1n7n8/?vd_source515e6808c21c69114a4fae34589dfb0e Python是什么 Python是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。具有很强的可读性,相比其他语言经常使用英文关键字&a…

为什么有时候磁珠会使电源的纹波变大

电路设计时,我们常常在芯片电源的输入放一个磁珠和电容,用以滤除电源上的高频噪声。 但是有时候会发现,加了磁珠后,芯片电源输入处纹波竟然变大了,超出了电源纹波范围,导致芯片工作异常。 把磁珠换成0R电阻…

论文阅读:Heterogeneous Graph Contrastive Learning for Recommendation(WSDM ’23)

论文链接 Motivation: 在推荐系统中,图神经网络在建模图结构数据上已经变成一个强有力的工具。但是现实生活的推荐语义通常涉及异质关系(像用户的社交关系,物品知识关系的依赖),这些都包含丰富的语义信息…

Linux下实现C语言程序

一.情况说明 写这篇博客的情况比较复杂,首先我本来是参加新星计划按照规划现在去学习shell脚本语言的,但是博主现在由于其他原因需要了解makefile,makefile是Linux系统下的一种工具,makefile的一些背景要涉及链接库的知识&#xf…

从0开始搭建一个简单的前后端分离的XX系统-vue+Springboot+mybatis-plus+mysql

一、准备工作 1.安装node 2.idea 旗舰版** idea**教程 上述教程中的idea**工具 3.安装mysql任意版本 mysql 4.安装mysql workbench(没用上) 5.安装navicate 参考文章:百度-从小白到架构(作者)-Navicat16** Nav…

Thinkphp获取项目最近更改变动的所有文件

导读: 企业级的网站项目都是要不断优化迭代更新的,做为一名后端程序员,在编写更新模块时,如何能快速获取最近修改的文件,然后打包压缩成更新补丁呢?我们先来看一下最终效果图: 步骤&#xff1a…

使用FFMPEG分离mp4/flv文件中的264视频和aac音频

准备 ffmpeg 4.4 一个MP4或flv格式的视频文件 分离流程 大致分为以下几个简单步骤: 1.使用avformat_open_input 函数打开文件并初始化结构AVFormatContext 2.查找是否存在音频和视频信息 3.构建一个h264_mp4toannexb比特流的过滤器,用来给视频avpa…

Hudi 数据湖技术之集成Flink

目录 1 安装Flink2 快速入门2.1 集成Flink概述2.2 环境准备2.3 创建表2.4 插入数据2.5 查询数据2.6 更新数据 3 Streaming query3.1 创建表3.2 查询数据3.3 插入数据 4 Flink SQL Writer4.1 Flink SQL集成Kafka4.2 Flink SQL写入Hudi4.2.1 创建Maven Module4.2.2 消费Kafka数据…

【C++】了解设计模式、 stackqueue的使用与模拟实现

文章目录 1.设计模式2.stack1.stack的使用1.stack的结构2.stack的接口 2.stack的模拟实现1.stack的结构2.接口实现 3.queue1.queue的使用1.queue的结构3.queue的接口 2.queue的模拟实现1.queue的结构2.接口实现 4.了解deque1.deque的原理介绍2.deque的底层结构3.deque的迭代器设…

Codeforces Round 861 (Div. 2)(A~D)

A. Lucky Numbers 给出边界l和r,在区间[l, r]之间找到幸运值最大的数字。一个数字的幸运值被定义为数位差的最大值,即数字中最大的数位和最小的数位的差。 思路:因为涉及到至少两位,即个位和十位变化最快,最容易得到相…

Android四大组件之广播接收者BroadcastReceiver

一、全局广播 Android中的广播可以分为两种类型:标准广播和有序广播 标准广播:一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会同一时刻接收到这条广播消息,因此它们之间没有任何先后顺序。无法进行…

Vector-常用CAN工具 - 入门到精通 - 专栏链接

一、CANoe篇 1、CANoe入门到精通_软件安装 2、CANoe入门到精通_硬件及环境搭建 3、CANoe入门到精通_软件环境配置 4、CANoe入门到精通_Network Node CAPL开发 5、CANoe入门到精通_Node节点开发基本数据类型 6、CANoe入门到精通_Test Node节点开发设置 7、CANoe入门到精通…

《Cocos Creator游戏实战》AIGC之将草稿内容转为真实内容

目录 前言 训练AI 从识别结果中提取必要数据 发送图片并生成最终代码 总结与提高 资源下载 前言 当创作灵感来的时候,我们可能会先把灵感记录在草稿上,之后再去实现它。比方说有一天,我突然来了游戏创作灵感,想着那可以先把…

gpt 怎么用-免费gpt下载使用方法

gpt 怎么用 GPT(Generative Pre-trained Transformer)是一种基于Transformer的神经网络模型,用于自然语言处理任务,例如文本生成、摘要生成、翻译、问答等。以下是使用GPT进行文本生成的一般步骤: 首先,您…

编译预处理

编译预处理 1、宏定义1.1、 无参宏定义1.2、使用宏定义的优点1.3、宏定义注意点1.4、带参数的宏(重点)1.5、条件编译1.6、宏定义的一些巧妙用法(有用)1.7、结构体占用字节数的计算原则(考题经常考,要会画图)1.8、#在宏定义中的作用&#xff0…

转型产业互联网,新氧能否再造辉煌?

近年来,“颜值经济”推动医美行业快速发展,在利润驱动下,除了专注医美赛道的企业之外,也有不少第三方互联网平台正强势进入医美领域,使以新氧为代表的医美企业面对不小发展压力,同时也展现出强大的发展韧性…

六、CANdelaStudio入门-通信参数编辑

本专栏将由浅入深的展开诊断实际开发与测试的数据库编辑,包含大量实际开发过程中的步骤、使用技巧与少量对Autosar标准的解读。希望能对大家有所帮助,与大家共同成长,早日成为一名车载诊断、通信全栈工程师。 本文介绍CANdelaStudio的通信参数编辑,欢迎各位朋友订阅、评论,…

Kubernetes 笔记(16)— 集群管理、使用名字空间分隔系统资源、给名字空间设置资源限额、默认资源配额的使用

1. 为什么要有名字空间 首先要明白,Kubernetes 的名字空间并不是一个实体对象,只是一个逻辑上的概念。它可以把集群切分成一个个彼此独立的区域,然后我们把对象放到这些区域里,就实现了类似容器技术里 namespace 的隔离效果&…

MATLAB符号运算(七) 更新中...

目录 1、实验目的: 2、实验内容: 1、实验目的: 1)掌握定义符号对象和创建符号表达式的方法; 2)掌握符号运算基本命令和规则; 3)掌握符号表达式的运算法则以及符号矩阵运算&#xf…

93、Dehazing-NeRF: Neural Radiance Fields from Hazy Images

简介 论文:https://arxiv.org/pdf/2304.11448.pdf 从模糊图像输入中恢复清晰NeRF 使用大气散射模型模拟有雾图像的物理成像过程,联合学习大气散射模型和干净的NeRF模型,用于图像去雾和新视图合成 通过将NeRF 3D场景的深度估计与大气散射模…