算法详解——回溯法

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

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

  • 排列和组合问题:例如求解全排列、子集合等问题,回溯法可以系统地生成所有可能的组合并逐一验证。
  • 决策问题:如八皇后问题、数独填充、图的着色问题等,这些问题需要在多个选择中找到符合特定约束的解。
  • 优化问题:如旅行商问题(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 False

    return True

def solve_n_queens(board, row):
    if row == len(board):
        print_solution(board)
        return True

    solution_found = False
    for col in range(len(board)):
        if is_safe(board, row, col):
            board[row][col] = 1
            if solve_n_queens(board, row + 1):
                solution_found = True
            board[row][col] = 0

    return solution_found

def print_solution(board):
    for row in board:
        print(" ".join('Q' if x == 1 else '.' for x in row))
    print("")

def main():
    n = 4
    board = [[0] * n for _ in range(n)]
    if not solve_n_queens(board, 0):
        print("没有找到解决方案")

main()

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows10搭建GPU版Darknet—yolov4—VS2022+CUDA+CUDNN(亲测有效)

1 VS2019安装 网址:Visual Studio: 面向软件开发人员和 Teams 的 IDE 和代码编辑器 下载完成之后双击.exe文件 步骤严格如下安装 默认语音包为中文(简体) 安装位置可以自行选择,完成以后就可以点击安装了。 安装完毕以后需要重启…

如何设置cPanel的自动备份

近期我们购买了Hostease美国VPS云主机产品,由于需要设置服务器的自动备份,我们向Hostease技术团队进行了咨询,他们提到VPS云主机的cPanel面板包含自动备份功能,下面我们就介绍如何进行自动备份的设置。 首先你需要登录到WHM面板&a…

暗区突围PC测试资格获取教程 人人可领100%获取方法

暗区突围PC测试资格获取教程 人人可领100%获取方法 暗区突围国际服的上线,近日在游戏圈内掀起了不小的浪花。而一个暗区突围国际服的测试资格更是成为了玩家们眼中炙手可热的宝物。许多玩家不知道该如何获取游戏的测试资格,今天小编就为大家带来详细的教…

电脑复制和粘贴的时候会出现Hello!

电脑不管是Microsoft Excel还是Microsoft Word复制之后粘贴过来就出现HELLO,当复制粘贴文件的时候就会出现WINFILE; 具体现象看下面两个图片: 这是因为winfile 文件病毒(幽灵蠕虫病毒),每月的28号发作; 症状…

【深度学习】YOLO源码中的mAP计算代码的理解笔记(大部分代码逐行+基础解释)

提示:本篇博客是在阅读了YOLO源码中的mAP计算方法的代码后加上官方解释以及自己的debug调试理解每一步是怎么操作的。由于是大部分代码进行了逐行解释,所以篇幅过长。 文章目录 前言一、输入格式处理1.1 转换公式二、init:初始化2.1 iouv2.2 …

2024版本idea集成SpringBoot + Ai 手写一个chatgpt 【推荐】

题目:SpringBoot OpenAi 在这里获取key和url:获取免费key base-url为这两个: 话不多说直接来! 一、简介 Spring AI 是 AI 工程的应用框架。其目标是将 Spring 生态系统设计原则(如可移植性和模块化设计&#xff…

【CAD建模号】学习笔记(四):工作平面

工作平面介绍 CAD建模号右侧导航栏提供了很多便捷的工具,有测量工具、坐标系、模型和图层切换、视图切换等。 1. 测量工具组 测量工具可以测量图形的几何体积,长度,角度等。工具组包含如下: 测量几何:可以测量图形的面…

C++多态实现原理详解

阅读引言: 我想象了一下, 假如人有突然问我什么是多态, 我该如何给别人说清楚呢?所以写下这篇文章, 希望大家看完有所收获。 ①. 开胃小菜 先看这样一个开胃小菜 这里我有点小小的疑惑, 大小为啥是1。 在C…

即插即用篇 | YOLOv8引入局部自注意力 HaloAttention | 为参数高效的视觉主干网络扩展局部自注意力

本改进已集成到 YOLOv8-Magic 框架。 我们提出了Axial Transformers,这是一个基于自注意力的自回归模型,用于图像和其他组织为高维张量的数据。现有的自回归模型要么因高维数据的计算资源需求过大而受到限制,要么为了减少资源需求而在分布表达性或实现的便捷性上做出妥协。相…

【知识碎片】2024_05_11

本篇记录了两个代码,【图片整理】是一个数组排序题,【寻找数组的中心下标】看起来很适合用双指针,但是细节多,最后还是没通过全部用例,看了题解写出来的。 C语言部分是两个知道错了之后恍然大悟的选择题。 每日代码 图…

1053: 输出利用先序遍历创建的二叉树中的指定结点的度

解法&#xff1a; c语言 #include<iostream> #include<vector> using namespace std; typedef struct tNodes{char val;tNodes* left, * right; }* tNode;void creat(tNode& t) {char ch;cin >> ch;if (ch #) t NULL;else {t new tNodes;t->val …

最少数量线段覆盖-华为OD

系列文章目录 文章目录 系列文章目录前言一、题目描述二、输入描述三、输出描述四、java代码五、测试用例 前言 本人最近再练习算法&#xff0c;所以会发布一些解题思路&#xff0c;希望大家多指教 一、题目描述 给定坐标轴上的一组线段&#xff0c;线段的起点和终点均为整数…

完整性验证器:迈向 Starknet 超高可扩展性的一大步

原文&#xff1a;https://www.starknet.io/en/content/the-integrity-verifier-a-leap-toward-starknet-hyperscaling&#xff1b;https://www.starknet.io/en/ecosystem/grant 编译&#xff1a;TinTinLand 核心观点 由 Herodotus 开发的完整性验证器&#xff0c;使开发者能够…

代码随想录算法训练营第六十三天| LeetCode84. 柱状图中最大的矩形

一、LeetCode 84. 柱状图中最大的矩形 题目链接/文章讲解/代码讲解&#xff1a;https://programmercarl.com/0084.%E6%9F%B1%E7%8A%B6%E5%9B%BE%E4%B8%AD%E6%9C%80%E5%A4%A7%E7%9A%84%E7%9F%A9%E5%BD%A2.html 状态&#xff1a;已解决 1.思路 这道题跟上道接雨水的题基本上是反…

【MySQL】锁

锁 全局锁 全局锁&#xff1a;对整个数据库实例加锁&#xff0c;加锁后整个实例就处于只读状态&#xff0c;其他语句都将被阻塞。 使用场景是&#xff1a;全库的逻辑备份 语法&#xff1a; 1、加全局锁 flush tables with read lock ;2、数据备份 mysqldump -uroot –pr…

【Web后端】web后端开发简介_Servlet简介

1.web后端开发简介 Java企业级开发&#xff0c;也就是学习]avaEE(Enterprise Edition)版本,是一种结构和一套标准。在应用中开发的标准就是Servlet、jsp和JavaBean技术。jsp技术现在已基本处于淘汰状态&#xff0c;简单了解即可web后端开发&#xff0c;基于B/S模式的开发体系。…

系分-历年论文题目

年份试题一试题二试题三试题四2023年信息系统数据转换与迁移敏捷开发方法论Devops及其应用论信息系统可行性分析2022年论原型法及其在信息系统开发中的应用论面向对象设计方法及其应用2021年论面向对象的信息系统分析方法论静态测试方法及其应用论富互联网应用的客户端开发技术…

13、FreeRTOS 事件标志组

文章目录 一、事件组(event group)的特性1.1 什么是事件标注组1.2 事件标注组的场景1.3 事件组的概念1.4 事件组的操作 二、事件组API2.1 创建2.2 删除2.3 设置事件2.4 等待事件2.5 同步点 一、事件组(event group)的特性 1.1 什么是事件标注组 事件标志位&#xff1a;表明某…

2024kali linux上安装java8

1 kali下载Java 8安装包 访问Oracle官网或其他可信的Java下载站点&#xff0c;如华为云的开源镜像站&#xff08;例如&#xff1a;https://repo.huaweicloud.com/java/jdk/8u202-b08/jdk-8u202-linux-x64.tar.gz&#xff09;。 确保下载的是与你的Kali Linux系统架构&#xf…

Collection工具类

Collection工具类的介绍 Collection 是一个操作Set、List和Map等集合的工具类Collection中提供了一些列静态的方法对集合元素进行排序、查询和修改的等操作 Collection的排序操作&#xff08;均为Static方法&#xff09; 1&#xff0c;reverse&#xff08;List&#xff09;&…