算法详解——回溯法

一、回溯法概述——问题背景

  回溯法是一种解决约束满足问题的方法,特别适用于解决组合问题、搜索优化问题等。它通过逐步构建候选解决方案并且在这个解决方案不再可能满足约束或条件时进行剪枝和回溯。具体来说,回溯法可以应用于以下类型的问题:

  • 排列和组合问题:例如求解全排列、子集合等问题,回溯法可以系统地生成所有可能的组合并逐一验证。
  • 决策问题:如八皇后问题、数独填充、图的着色问题等,这些问题需要在多个选择中找到符合特定约束的解。
  • 优化问题:如旅行商问题(TSP)和其他需要找到最优解的问题,回溯法可以遍历所有可能的解,找到成本最低或收益最高的解。
  • 分割问题:例如分割等和子集、装箱问题等,需要将集合分割成满足特定条件的多个子集。

二、回溯法思想——基本过程

  回溯法的基本思想是在包含问题所有可能解的解空间树中,采用深度优先搜索策略来探索解决方案。这一过程从解空间树的根节点开始,逐层深入每一个节点进行探索。在探索到任何一个节点时,首先需要判断该节点是否可能包含问题的解。如果判断为是,算法将继续从这个节点深入,探索所有可能的子节点;如果判断为否,则表明以当前节点为根的子树不会包含问题的有效解,因此无需进一步探索这一路径。

  这时,算法将执行“剪枝”操作,即停止当前路径的进一步探索并退回到其父节点,继续探索其他可能的子节点。通过这种方式,回溯法避免了无效搜索和不必要的计算,从而提高了搜索效率。整个过程不断重复,直到探索完整个解空间树或找到满足条件的解为止。这种策略确保了算法可以系统地覆盖所有可能的解决方案,同时在不满足条件的情况下及时撤退,节省资源。

三、回溯法应用——四皇后问题

   N N N 皇后问题是一种经典的组合优化问题,目标是在一个 N × N N×N N×N 的棋盘上放置 N N N 个皇后棋子,使得这些皇后彼此之间不发生冲突。在国际象棋中,皇后可以在水平、垂直或任意45°斜线方向上移动。因此,解决这一问题的关键在于确保任意两个皇后不能位于同一行、同一列或同一对角线上。为了达成这一目标,我们需要找到一种放置方法,使得棋盘上的每一行、每一列以及所有的主要和次要对角线上都至多只有一个皇后。解决这一问题可以帮助研究和理解更广泛的约束满足和搜索优化问题,同时也是探索算法设计和问题求解技巧的一种方式。如下图即使四皇后问题的一种解:

在这里插入图片描述

  四皇后问题可以通过构建和探索一个解空间树来求解。解空间树是一个抽象结构,用于表示所有可能的解决方案路径。在四皇后问题中,每个节点代表棋盘的一个状态,即某些皇后已经放置在棋盘上的位置。根节点是一个空棋盘,而每个子节点表示在棋盘上新增一个皇后的尝试。解空间树的每一层对应于棋盘的一行,其中每个节点尝试将一个皇后放在那一行的不同列中。我们从根节点开始,按照深度优先的策略探索这棵树。

解空间树的探索过程

  1. 根节点与层次结构:

  根节点代表一个空棋盘,即开始状态。从这里出发,第一层的四个子节点分别尝试在第一行的四列中放置一个皇后。每个子节点又将生成自己的子节点,这些子节点尝试在第二行放置皇后,而且必须确保不与第一行的皇后冲突。

  1. 深度优先搜索与回溯:

  搜索从根节点开始,深入到解空间树的第一层,尝试在第一行的每一列中放置一个皇后。对于每个位置,如果安全,则递归地进入下一层,也就是下一行,尝试放置另一个皇后。

  • 安全性检查:在尝试在棋盘的某行某列放置皇后之前,会检查该位置是否与已放置的皇后有列冲突或对角线冲突。

  • 递归深入:如果当前节点(即棋盘配置)安全,则在下一层继续放置皇后。

  • 回溯:如果在当前行无法找到一个安全的列位置,这表明当前路径不可能导致解决方案,因此算法会回溯到上一层,即上一行,移除上一行的皇后,尝试在其他列放置。

  1. 剪枝:

  在搜索过程中,如果一个节点已确定不可能导致有效解(例如,如果第一行和第二行的皇后在同一列),则无需探索这个节点的任何子节点。这种“剪枝”操作减少了不必要的计算,优化了搜索过程。

  1. 找到解决方案:

  当到达解空间树的底部,即成功在所有四行中放置了皇后,并且所有放置都是安全的,那么这个路径(从根到当前节点的路径)就是一个解决方案。如果未到达底部就无路可走,则需要回溯。

  1. 枚举所有可能的解决方案:

  通过从根节点到解空间树的每一个叶节点的遍历,我们可以找出所有可能的解决方案。棋盘上每一行的每一个合法位置都将被考虑一次,确保全面性。

  通过这种方式,四皇后问题的解空间树提供了一种系统的方法来探索所有可能的解决方案,并有效地避开了不可能的解决方案路径。这不仅显著提高了效率,而且确保了解决方案的完整性。

解决过程与原理

  1. 棋盘初始化:
      棋盘是一个4x4的二维数组,其中的每个元素初始设为0,表示该位置没有放置皇后。棋盘的每一行将尝试放置一个皇后。

  2. 安全性检查:

  在尝试将一个皇后放置在棋盘的某个位置时,必须确保该位置与已放置的其他皇后没有冲突。这涉及到三个方向的检查:

  • 列检查:确保当前列上没有其他皇后。

  • 左上对角线检查:检查从当前位置开始向左上方延伸的对角线上是否有其他皇后。

  • 右上对角线检查:检查从当前位置开始向右上方延伸的对角线上是否有其他皇后。

  这些检查确保任何两个皇后都不会在同一行、列或对角线上,从而避免了相互攻击。

  1. 递归与回溯:

  使用递归函数来尝试在每一行放置一个皇后。对于每一行,函数遍历所有列,并使用安全性检查判断是否可以在当前列放置皇后:

  • 如果当前位置安全,则放置皇后并递归地调用该函数以尝试在下一行放置另一个皇后。

  • 如果成功在所有行放置了皇后,则当前的棋盘配置是一个有效解。

  • 如果在某行中找不到安全的列来放置皇后,则函数将回溯到上一行,移除那一行的皇后,并尝试下一个列位置。

  • 这个过程将持续递归和回溯,直到所有可能的行和列的组合都被尝试过。

  1. 打印解决方案:

  一旦找到一个有效的棋盘配置,即所有皇后都安全地放置,便打印该配置。如果解空间中存在多个解,每个解都会被打印出来。

Python代码实现

def is_safe(board, row, col):# 检查列冲突for i in range(row):if board[i][col] == 1:return False# 检查左上对角线冲突for i, j in zip(range(row, -1, -1), range(col, -1, -1)):if board[i][j] == 1:return False# 检查右上对角线冲突for i, j in zip(range(row, -1, -1), range(col, len(board))):if board[i][j] == 1:return Falsereturn Truedef solve_n_queens(board, row):if row == len(board):print_solution(board)return Truesolution_found = Falsefor col in range(len(board)):if is_safe(board, row, col):board[row][col] = 1if solve_n_queens(board, row + 1):solution_found = Trueboard[row][col] = 0return solution_founddef print_solution(board):for row in board:print(" ".join('Q' if x == 1 else '.' for x in row))print("")def main():n = 4board = [[0] * n for _ in range(n)]if not solve_n_queens(board, 0):print("没有找到解决方案")main()

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

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

相关文章

基于yolov5+gradio目标检测演示系统设计

YOLOv5与Gradio:目标检测可视化展示的新篇章 随着人工智能技术的深入发展,目标检测已成为现代智能应用中的一项关键技术。YOLOv5,作为目标检测领域的杰出代表,凭借其出色的实时性和准确性,赢得了广泛的认可和应用。而…

AI视频教程下载:用ChatGPT自动化各种工作任务

这是一门实用的无代码课程,旨在通过使用ChatGPT高级数据分析和代码解释器提高生产力。 通过让ChatGPT代码解释器创建程序来自动化单调的任务,提高您的计算机生产力。 这门课程专为那些渴望快速使用小型实用程序的人设计,不需要编程知识。相…

Java医院绩效管理应用系统源码java+ maven+ avue 公立医院绩效考核管理系统源码 支持二开

Java医院绩效管理应用系统源码java maven avue 公立医院绩效考核管理系统源码 支持二开 医院绩效管理系统解决方案紧扣新医改形势下医院绩效管理的要求,以“工作量为基础的考核方案”为核心思想,结合患者满意度、服务质量、技术难度、工作效率、医德医风…

Spring Boot进阶 - Starter自定义

在Spring Boot中,自定义starter是一种高级用法,它允许你封装特定功能或组件,使得其他开发者能够轻松地在他们的Spring Boot应用中引入和配置这些功能,而无需关注其实现细节。自定义starter本质上是一个jar包,它集合了自动配置、依赖管理和可选的模板代码,以简化集成过程。…

uni-app 自定义tabbar

uni-app 自定义tabbar 第一步&#xff1a;在components下创建目录tabbar&#xff0c;再在tabbar目录下创建tabbar.vue文件 <template><view class"tabbar jsf-around"><view class"tabbar-item dis-c align-center " v-for"(item,in…

如何使用 WavLM音频合成模型

微软亚洲研究院与 Azure 语音组的研究员们提出了通用语音预训练模型 WavLM。通过 Denoising Masked Speech Modeling 框架&#xff08;核心思想是通过预测被掩蔽&#xff08;即遮蔽或删除&#xff09;的语音部分来训练模型&#xff0c;同时还包括去噪的过程&#xff09;&#x…

使用单片机在图形点阵LCD上绘制波形图

使用单片机在图形点阵LCD上绘制波形图 需求&#xff1a; 假如有一组浮点数据&#xff0c;是通过AD转换得到的&#xff0c;保存在数组MyArray[]中&#xff0c;采集点数为len&#xff0c;采集周期为T&#xff0c;现在想用单片机在LCD上绘制出这组数据对应的波形图&#xff0c;该…

本地连接服务器Jupyter【简略版】

首先需要在你的服务器激活conda虚拟环境&#xff1a; 进入虚拟环境后使用conda install jupyter命令安装jupyter&#xff1a; 安装成功后先不要着急打开&#xff0c;因为需要设置密码&#xff0c;使用jupyter notebook password命令输入自己进入jupyter的密码&#xff1a; …

Python国内常用镜像源汇总

前言 由于网络问题&#xff0c;直接从Python官方的PyPI仓库下载软件包可能会遇到速度慢甚至无法访问的情况。还好&#xff0c;有几个国内大学和组织提供了PyPI的镜像&#xff0c;可以显著提高下载速度和稳定性。本文将介绍几个常用的Python镜像源&#xff0c;并指导如何在pip中…

新能源汽车动力电池浸没式冷却方案介绍与未来趋势

前言 新能源汽车的兴起标志着汽车工业的一次革命&#xff0c;其中动力电池的设计与性能成为了关键。浸没式冷却方案作为一种新兴的技术&#xff0c;为动力电池系统提供了有效的散热解决方案&#xff0c;其在未来的发展趋势备受关注。 一 动力电池浸没式冷却方案介绍 首先&am…

用python写算法——栈笔记

栈 栈的定义相关算法题 栈的定义 1.它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶&#xff0c;相对地&#xff0c;把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈&#xff0c;它是把新元素放到栈顶元素的上面&#xff0…

IIS配置SSL,根据pem和key生成pfx,openssl的版本不能太高

1、生成pfx文件 供应商给的文件是pef和key后缀的两个文件&#xff0c;在IIS里不好导入(如果有知道好导入的可以给我留言&#xff0c;谢谢。)。 1.1 下载OpenSSL工具&#xff0c;并安装。 主要用于将.pem文件转成.pfx文件。 下载OpenSSL的链接&#xff1a;http://slproweb.com/…

设计模式-结构型-适配器模式-Adapter

地址类 public class Address {public void street() {System.out.println("普通的街道");}public void zip() {System.out.println("普通的邮政编码");}public void city() {System.out.println("普通的城市");} } 荷兰地址类 public class …

飞书API(8):MySQL 入库定制版本

一、引入 通用版能解决百分之八九十的任务&#xff0c;剩下的部分任务需要进行定制。 先说明通用版本和定制版本有什么不同&#xff0c;通用版本就是只管大的数据类型&#xff0c;将数据处理为对应的类型入库&#xff0c;而定制版本会考虑局部列的数据类型&#xff0c;。举个…

10分钟了解Golang泛型

泛型是Golang在1.18版本引入的强大工具&#xff0c;能够帮助我们在合适的场合实现简洁、可读、可维护的代码。原文: Go Generics: Everything You Need To Know 导言 可能有人会觉得Go泛型很难&#xff0c;因此想要借鉴其他语言&#xff08;比如Java、NodeJS&#xff09;的泛型…

class常量池、运行时常量池和字符串常量池详解

类常量池、运行时常量池和字符串常量池这三种常量池&#xff0c;在Java中扮演着不同但又相互关联的角色。理解它们之间的关系&#xff0c;有助于深入理解Java虚拟机&#xff08;JVM&#xff09;的内部工作机制&#xff0c;尤其是在类加载、内存分配和字符串处理方面。 类常量池…

一个小球从100米落下,每次落下弹起的高度是上一次的一半,问需要几次后高度小于10米

一个小球从100米落下&#xff0c;每次落下弹起的高度是上一次的一半&#xff0c;问需要几次后高度小于10米&#xff1f;我练习所以用了 // 匿名函数 let fren 0; let fre function(height) {for (let i 0; height > 10; i) {fren;height height * 0.5}return fren; } c…

湖南知识付费系统开发公司,教育机构如何提高转化率?有哪些途径?

教育行业必须线上线下一起抓。当下教育机构不得不考虑线上招生、线上教学和服务。但是大多数人&#xff1a;没思路、没人才&#xff0c;不知道如何下手?其实线上运营也没那么难&#xff0c;“危机”即“机遇”。教育机构如何提高转化率&#xff1f;有哪些途径&#xff1f; 一、…

基于STM32单片机的室内温湿度及PM2.5浓度监测报警系统

基于STM32单片机的室内温湿度及PM2.5浓度监测报警系统 摘要&#xff1a; 本文设计并实现了一个基于STM32单片机的室内温湿度及PM2.5浓度监测报警系统。该系统通过集成温湿度传感器和PM2.5传感器&#xff0c;实时监测室内环境参数&#xff0c;并将数据通过液晶显示屏实时显示。…

docker修改默认安装路径

docker安装之后默认在 /etc/docker 在/etc/docker 文件下有一个daemon -json 没有就新增 {"registry-mirrors": ["https://kfwkfulq.mirror.aliyuncs.com","https://2lqq34jg.mirror.aliyuncs.com","https://pee6w651.mirror.aliyuncs.c…