常见算法思想:回溯法

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析

阶段4、深入jdk其余源码解析

阶段5、深入jvm源码解析

回溯法

回溯法也叫试探法,试探的处事方式比较委婉,它先暂时放弃关于问题规模大小的限制,并将问题的候选解按某种顺序逐一进行枚举和检验。当发现当前候选解不可能是正确的解时,就选择下一个候选解。如果当前候选解除了不满足问题规模要求外能够满足所有其他要求时,则继续扩大当前候选解的规模,并继续试探。如果当前候选解满足包括问题规模在内的所有要求时,该候选解就是问题的一个解。在试探算法中,放弃当前候选解,并继续寻找下一个候选解的过程称为回溯。扩大当前候选解的规模,以继续试探的过程称为向前试探。

使用回溯法解题的基本步骤如下所示:

(1)针对所给问题,定义问题的解空间。
(2)确定易于搜索的解空间结构。
(3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。

回溯法为了求得问题的正确解,会先委婉地试探某一种可能的情况。在进行试探的过程中,一旦发现原来选择的假设情况是不正确的,马上会自觉地退回一步重新选择,然后继续向前试探,如此这般反复进行,直至得到解或证明无解时才死心。

效率分析

下面是回溯的3个要素。
(1)解空间:表示要解决问题的范围,不知道范围的搜索是不可能找到结果的。
(2)约束条件:包括隐性的和显性的,题目中的要求以及题目描述隐含的约束条件,是搜索有解的保证。
(3)状态树:是构造深搜过程的依据,整个搜索以此树展开。

回溯算法适合解决没有要求求最优解的问题。如果采用,一定要注意跳出条件及搜索完成的标志,否则会陷入泥潭不可自拔。

下面是影响算法效率的因素:

  • 搜索树的结构,解的分布,约束条件的判断。
  • 改进回溯算法的途径。
  • 搜索顺序。
  • 节点少的分支优先,解多的分支优先。
  • 让回溯尽量早发生。

回溯法搜索解空间时,通常采用两种策略避免无效搜索,提高回溯的搜索效率:

  • 用约束函数在扩展结点处剪除不满足约束的子树;
  • 用限界函数剪去得不到问题解或最优解的子树。

例题

N皇后问题:在一个N*N大小的国际象棋棋盘上放置N个皇后棋子,使得所有的皇后都是安全的(即任意两个皇后都无法攻击到对方)。

分析:

为缩小规模,我们用显示的国际象棋8*8的八皇后来分析。按照国际象棋的规则,皇后的攻击方式是横,竖和斜向。
皇后可以攻击到同一列所有其它棋子,因此可推导出每1列只能存在1个皇后,即每个皇后分别占据一列。棋盘一共8列,刚好放置8个皇后。

为了摆放出满足条件的8个皇后的布局,可以按如下方式逐步操作:

  1. 在第0行找到一个位置放置第1个皇后;
  2. 在第1行找到一个位置放置第2个皇后;
  3. 在第2行找到一个位置放置第3个皇后;
  4. 对第3,4,5,6,7行都执行放置操作;
  5. 当执行完“在第7行找到一个放置第8个皇后”这一操作完毕后,问题求解完毕。
    观察1,2,3,4 这些操作步骤,可以发现是一个重复的动作,抽象一下,即“在第 n 行放下第 n+1 个皇后”,n 从0到7。

把规模放大到N行N列也一样,下面用回溯法解决N皇后问题:

Go语言描述
    const N = 8func NQueens() {// 开辟一个一维数组保存可能的结果result := make([]int, N)// 从第一行开始试探放置棋子place(result, 0)}// 递归:在保证已放置行安全情况下,放置下一行棋子func place(result []int, row int) {// 所有行棋子放满后输出if row == N {fmt.Println(result) // 输出答案return}// 逐列试探for column := 0; column < N; column++ {// 试探在 column 列 处放下棋子,并检验是否安全result[row] = columnif safe(result, row) {// 棋子安全,放置下一行棋子place(result, row+1)}}}// 验证当前棋子是否安全func safe(result []int, row int) bool {// 循环验证是否互相攻击for c := 0; c < row; c++ {if isAttack(result, c, row) {return false}}return true}// 攻击试探,如果被攻击则返回truefunc isAttack(result []int, c int, row int) bool {switch {case result[c] == result[row]:return truecase result[row]-result[c] == c-row:return truecase result[row]-result[c] == row-c:return true}return false}

执行:

    func TestNQueens(t *testing.T) {NQueens()}=== RUN   TestNQueens[0 4 7 5 2 6 1 3][0 5 7 2 6 3 1 4][0 6 3 5 7 1 4 2][0 6 4 7 1 3 5 2][1 3 5 7 2 0 6 4][1 4 6 0 2 7 5 3][1 4 6 3 0 7 5 2][1 5 0 6 3 7 2 4][1 5 7 2 0 3 6 4][1 6 2 5 7 4 0 3][1 6 4 7 0 3 5 2][1 7 5 0 2 4 6 3][2 0 6 4 7 1 3 5][2 4 1 7 0 6 3 5][2 4 1 7 5 3 6 0][2 4 6 0 3 1 7 5][2 4 7 3 0 6 1 5][2 5 1 4 7 0 6 3][2 5 1 6 0 3 7 4][2 5 1 6 4 0 7 3][2 5 3 0 7 4 6 1][2 5 3 1 7 4 6 0][2 5 7 0 3 6 4 1][2 5 7 0 4 6 1 3][2 5 7 1 3 0 6 4][2 6 1 7 4 0 3 5][2 6 1 7 5 3 0 4][2 7 3 6 0 5 1 4][3 0 4 7 1 6 2 5][3 0 4 7 5 2 6 1][3 1 4 7 5 0 2 6][3 1 6 2 5 7 0 4][3 1 6 2 5 7 4 0][3 1 6 4 0 7 5 2][3 1 7 4 6 0 2 5][3 1 7 5 0 2 4 6][3 5 0 4 1 7 2 6][3 5 7 1 6 0 2 4][3 5 7 2 0 6 4 1][3 6 0 7 4 1 5 2][3 6 2 7 1 4 0 5][3 6 4 1 5 0 2 7][3 6 4 2 0 5 7 1][3 7 0 2 5 1 6 4][3 7 0 4 6 1 5 2][3 7 4 2 0 6 1 5][4 0 3 5 7 1 6 2][4 0 7 3 1 6 2 5][4 0 7 5 2 6 1 3][4 1 3 5 7 2 0 6][4 1 3 6 2 7 5 0][4 1 5 0 6 3 7 2][4 1 7 0 3 6 2 5][4 2 0 5 7 1 3 6][4 2 0 6 1 7 5 3][4 2 7 3 6 0 5 1][4 6 0 2 7 5 3 1][4 6 0 3 1 7 5 2][4 6 1 3 7 0 2 5][4 6 1 5 2 0 3 7][4 6 1 5 2 0 7 3][4 6 3 0 2 7 5 1][4 7 3 0 2 5 1 6][4 7 3 0 6 1 5 2][5 0 4 1 7 2 6 3][5 1 6 0 2 4 7 3][5 1 6 0 3 7 4 2][5 2 0 6 4 7 1 3][5 2 0 7 3 1 6 4][5 2 0 7 4 1 3 6][5 2 4 6 0 3 1 7][5 2 4 7 0 3 1 6][5 2 6 1 3 7 0 4][5 2 6 1 7 4 0 3][5 2 6 3 0 7 1 4][5 3 0 4 7 1 6 2][5 3 1 7 4 6 0 2][5 3 6 0 2 4 1 7][5 3 6 0 7 1 4 2][5 7 1 3 0 6 4 2][6 0 2 7 5 3 1 4][6 1 3 0 7 4 2 5][6 1 5 2 0 3 7 4][6 2 0 5 7 4 1 3][6 2 7 1 4 0 5 3][6 3 1 4 7 0 2 5][6 3 1 7 5 0 2 4][6 4 2 0 5 7 1 3][7 1 3 0 6 4 2 5][7 1 4 2 0 6 3 5][7 2 0 5 1 4 6 3][7 3 0 2 5 1 6 4]--- PASS: TestNQueens (0.00s)PASS

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

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

相关文章

E - Rainbow Strings

如果字符串中的每个字母都不同&#xff0c;则将字符串定义为彩虹字符串。空字符串也被认为是彩虹字符串。 给定一个小写字母字符串&#xff0c;计算彩虹字符串的不同子序列的数量。如果一个子序列中包含索引&#xff0c;但另一个子序列不包含索引&#xff0c;则即使生成的字符串…

ORM-06-jooq 入门介绍

拓展阅读 The jdbc pool for java.(java 手写 jdbc 数据库连接池实现) The simple mybatis.&#xff08;手写简易版 mybatis&#xff09; JOOQ JOOQ 可以通过数据库直接生成 java 代码&#xff0c;通过 flent-api 进行数据库操作。 SQL builder JOOQ 非常的灵活和强大。你可…

【XR806开发板试用】编译中的几个问题以及hello跑起来

首先我们先看https://xr806.docs.aw-ol.com/ 该文档部分不适应 当前最新gitee 如果没有repo工具&#xff0c;可通过下面的git命令获取repo。 git clone https://gerrit-googlesource.lug.ustc.edu.cn/git-repo下载代码 没有使用ssh://方式 过于麻烦 mkdir xr806_openharmony…

加载服务端发送的模型文件_unity开发进阶

加载服务端发送的模型文件 前言一、服务端搭建二、unity请求文件三、加载模型结语 前言 之前我们学习制作的都是离线状态下的东西&#xff0c;今天我们学习制作一个小demo。 内容就是我们用unity请求后台&#xff0c;接受后台发送过来的模型&#xff0c;然后将模型加载到场景中…

0125-2-Vue深入学习1—mustache模板引擎原理

[mustache] 是 “胡子”的意思&#xff0c;因为它的嵌入标记 {{ }} 旋转过来很像[胡子]&#xff0c;Vue中的 {{ }} 语法也引用了mustache&#xff0c;这也是我深入学习的目的。 1、原始js方式使 数据 变为视图 <ul id"list"></ul><script>var arr …

k8s---安全机制

k8s的安全机制&#xff0c;分布式集群管理工具&#xff0c;就是容器编排。安全机制的核心&#xff1a;APIserver。为整个集群内部通信的中介&#xff0c;也是外控控制的入口。所有的机制都是围绕apiserver来进行设计&#xff1a; 请求api资源&#xff1a; 1、认证 2、鉴权 …

快速上手的AI工具-文心一言绘本创作

前言 大家好晚上好&#xff0c;现在AI技术的发展&#xff0c;它已经渗透到我们生活的各个层面。对于普通人来说&#xff0c;理解并有效利用AI技术不仅能增强个人竞争力&#xff0c;还能在日常生活中带来便利。无论是提高工作效率&#xff0c;还是优化日常任务&#xff0c;AI工具…

js计算皮尔逊相关系数

代码如下; let XGX {correlationCoefficient(pA, pB) {let covXY -pA * pBlet varX pA * (1-pA) let varY (1-pB)* pBlet res covXY / (Math.sqrt(varX*varY, 2))return res},correlation(x,y){x[0.3,50.2,99.5,199.3,299,398];y[0.1,50,99.9,200,300,400];// 计算均值con…

Linux操作系统概念

绪论​&#xff1a; “心灵纯洁的人&#xff0c;生活充满甜蜜和喜悦。——列夫托尔斯泰”&#xff0c;本章的主要内容是介绍了硬件的组成结构冯诺依曼体系结构以及操作系统的概念和操作系统的作用&#xff0c;本章的内容主要是理论他起到承上启下的作用只有理解了操作系统的运行…

rs3568芯片,hdmi输出 无声音

rs3568芯片&#xff0c;hdmi in输入 hdmi输出 无声音&#xff0c;如果高手请联系。谢谢&#xff01;

【硅谷甄选】stylelint

配置 stylelint stylelint 为 css 的 lint 工具。可格式化 css 代码&#xff0c;检查 css 语法错误与不合理的写法&#xff0c;指定 css 书写顺序等。 以下使用 scss 作为预处理器为例&#xff0c;安装以下依赖&#xff1a; pnpm add sass sass-loader stylelint postcss po…

SAP创建资产号码和分配资产价值

文章目录 1 Creat new asset2 View asset3 Create old asset4 Transfer value5 Summary 1 Creat new asset T-code(AS01) 2 View asset T-CODE : AS03 3 Create old asset T-code(as91) 4 Transfer value T-code(ABLDT) If there is following information a…

python sqlite3 线程池封装

1. 封装 sqlite3 1.1. 依赖包引入 # -*- coding: utf-8 -*- #import os import sys import datetime import loggingimport sqlite31.2. 封装类 class SqliteTool(object):#def __init__(self, host, port, user, password, database):def __init__(self, host, database):s…

Typora + PicGo + GitHub搭建图床

Typora PicGo GitHub搭建图床 1. Typora下载破解 这一步自行百度 2. PicGo下载 PicGo is Here | PicGo 自行下载安即可 3. GitHub仓库设置 gitHub注册略过&#xff0c;如果不能访问请科学上网 创建仓库 生成访问token 点击右上角头像 -> setting -> 点击左边最…

Hotspot源码解析-第25章-类的初始化

第25章-类的初始化 这一章主要是讲类的初始化操作&#xff0c;后续类加载章节中也会用到这一章的知识&#xff0c;只不过&#xff0c;这里就讲&#xff0c;是因为虚拟在初始化过程中&#xff0c;需要对基础类&#xff0c;比如System/Thread等类进行初始化操作&#xff0c;所以…

第三季《乐队风暴》全国总决赛圆满落幕

2024年1月21日&#xff0c;由广东珠江、盛娱星汇海选联合主办的第三季《乐队风暴》全国海选歌手赛道全国总决赛在广州罗格镇MUSIC LIVE&#xff08;太古仓店&#xff09;正式打响&#xff0c;第三季《乐队风暴》全国海选开启以来共有超8000人报名渴望登上绚丽舞台&#xff0c;从…

二叉搜索树、二叉排序树(查找、插入和删除)——Java版本

1. 概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值它的左右子树也分别…

Rsync服务

一、Rsync概述 rsync英文称为 remote synchronizetion&#xff0c;rsync具有可使本地和远程两台主机之间的数据快速复制同步镜像、远程备份的功能&#xff0c;功能类似于ssh带的scp命令&#xff0c;优于scp命令的功能&#xff0c;scp每次都是全量拷贝&#xff0c;而rsync可以增…

Rust Web小项目

Rust 第26节 Web小项目 监听TCP链接 use std::net::TcpListener;fn main() {let listener TcpListener::bind("127.0.0.1:7887").unwrap(); //监听7887端口&#xff0c;成功后&#xff0c;就创建一个linstenerfor stream in listener.incoming() { // listener.…

2024年mongodb自建三节点副本集详细教程

环境说明 系统centos7.9 自建服务器或云服务器&#xff0c;硬件要求不低于2核2G内存&#xff0c;20G硬盘&#xff0c;文件系统默认是ext4即可。 生产环境最好单独一个磁盘存放数据库&#xff0c;方便数据备份和还原&#xff0c;避免干扰到其他磁盘的运作。 mongodb 4.4.27 …