【回溯】n皇后问题Python实现

文章目录

    • @[toc]
      • 问题描述
      • 问题转换
      • 回溯法
      • 时间复杂性
      • `Python`实现

因上努力

个人主页:丷从心

系列专栏:回溯法

果上随缘


问题描述

  • 有一批共 n n n个集装箱要装上 2 2 2艘载重量分别为 c 1 c_{1} c1 c 2 c_{2} c2的轮船,其中集装箱 i i i的重量为 w i w_{i} wi,且 ∑ i = 1 n w i ≤ c 1 + c 2 \displaystyle\sum\limits_{i = 1}^{n}{w_{i}} \leq c_{1} + c_{2} i=1nwic1+c2
  • 是否有一个合理的装载方案可将这 n n n个集装箱装上这两艘轮船

问题转换

  • 先将第一艘轮船尽可能装满,然后将剩余的集装箱装上第二艘轮船
  • 装载问题等价于以下特殊的 0 − 1 0-1 01背包问题

{ max ⁡ ∑ i = 1 n w i x i s . t . ∑ i = 1 n w i x i ≤ c 1 x i ∈ { 0 , 1 } , 1 ≤ i ≤ n \begin{cases} \max{\displaystyle\sum\limits_{i = 1}^{n}{w_{i} x_{i}}} \\ s.t. \displaystyle\sum\limits_{i = 1}^{n}{w_{i} x_{i}} \leq c_{1} \end{cases} \kern{2em} x_{i} \in \set{0 , 1} , 1 \leq i \leq n maxi=1nwixis.t.i=1nwixic1xi{0,1},1in


回溯法

  • 用子集树表示解空间,根节点为第 0 0 0
  • 约束函数用于剪去不满足约束条件 ∑ i = 1 n w i x i ≤ c 1 \displaystyle\sum\limits_{i = 1}^{n}{w_{i} x_{i}} \leq c_{1} i=1nwixic1的子树
    • 在子集树的第 j j j层的结点 Z Z Z处,用 c w cw cw记为当前的装载重量,即 c w = ∑ i = 1 j w i x i cw = \displaystyle\sum\limits_{i = 1}^{j}{w_{i} x_{i}} cw=i=1jwixi
    • c w > c 1 cw > c_{1} cw>c1时,以结点 Z Z Z为根的子树中所有结点都不满足约束条件,因而该子树中的解均为不可行解,故可将该子树剪去
  • 限界函数用于剪去不含最优解的子树,从而改进算法在平均情况下的运行效率
    • Z Z Z是解空间树第 i i i层上的当前扩展结点, c w cw cw是当前载重量, b e s t w bestw bestw是当前最优载重量, r r r是剩余集装箱的重量,即 r = ∑ j = i + 1 n w j r = \displaystyle\sum\limits_{j = i + 1}^{n}{w_{j}} r=j=i+1nwj
    • 定义限界函数为 c w + r cw + r cw+r,在以 Z Z Z为根的子树中任一叶节点所相应的重量均不超过 c w + r cw + r cw+r,当 c w + r ≤ b e s t w cw + r \leq bestw cw+rbestw时,可将 Z Z Z的子树剪去
  • i = n i = n i=n时,算法搜索至叶结点,其相应的装载重量为 c w cw cw,如果 c w > b e s t w cw > bestw cw>bestw,则表示当前解优于当前最优解,此时更新 b e s t w bestw bestw
  • i < n i < n i<n时,当前扩展节点 Z Z Z是子集树中的内部结点,该结点的左儿子表示 x [ i + 1 ] = 1 x[i + 1] = 1 x[i+1]=1的情形,仅当 c w + w [ i + 1 ] ≤ c 1 cw + w[i + 1] \leq c_{1} cw+w[i+1]c1且满足限界函数时进入左子树,对左子树递归搜索,该结点的右儿子表示 x [ i + 1 ] = 0 x[i + 1] = 0 x[i+1]=0的情形,由于可行结点的右儿子结点总是可行的,因此进入右子树时不需要检查约束函数,只需要检查限界函数

时间复杂性

  • 在每个结点处算法花费 O ( n ) O(n) O(n)时间,子集树中结点个数为 O ( 2 n ) O(2^{n}) O(2n),故时间复杂性为 O ( n 2 n ) O(n 2^{n}) O(n2n)

Python实现

def backtrack_loading(weights, capacity):n = len(weights)best_solution = []best_value = 0def constraint(solution):# 约束函数: 检查当前解是否满足容量限制total_weight = sum(item for item in solution)return total_weight <= capacitydef bound(solution, index):# 限界函数: 计算当前解的重量总和加上剩余物品重量作为上界, 用于剪枝total_weight = sum(item for item in solution) + sum(weight for weight in weights[index + 1:])return total_weightdef backtrack(solution, value, index):nonlocal best_solution, best_valueif index == n:# 已经遍历完所有物品if value > best_value:# 如果当前解的重量更大, 更新最优解best_solution = solutionbest_value = valuereturn# 尝试选择当前物品weight = weights[index]if constraint(solution + [weight]) and bound(solution + [weight], index) >= best_value:# 如果满足约束函数, 继续探索下一个物品backtrack(solution + [weight], value + weight, index + 1)# 尝试不选择当前物品if bound(solution, index) >= best_value:# 如果当前解的上界仍然可能更好, 继续探索下一个物品backtrack(solution, value, index + 1)# 开始回溯搜索backtrack([], 0, 0)return best_solution, best_valueweights = [2, 4, 5, 7]
capacity = 10best_solution, best_value = backtrack_loading(weights, capacity)print(f'最优解: {best_solution}')
print(f'最优值: {best_value}')
最优解: [2, 7]
最优值: 9

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

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

相关文章

c# OpenCvSharp透视矫正六步实现透视矫正(八)

透视矫正,引用文档拍照扫描&#xff0c;相片矫正这块。 读取图像Cv2.ImRead();预处理&#xff08;灰度化&#xff0c;高斯滤波、边缘检测&#xff09;轮廓检测&#xff08;获取到最大轮廓&#xff09;获取最大面积轮廓的四个顶点标识最小矩形坐标透视矫正显示 完整代码 // 1、…

【数据结构】LRU缓存的简单模拟实现(leetcode力扣146LRU缓存)

文章目录 一、定义二、LRU模拟实现二、代码实现 一、定义 LRU是Least Recently Used的缩写&#xff0c;意思是最近最少使用&#xff0c;它是一种Cache替换算法。 Cache的容量有限&#xff0c;因此当Cache的容量用完后&#xff0c;而又有新的内容需要添加进来时&#xff0c; 就…

\r\n和缓冲区/进度条小程序

一 前置知识 带有\n就会立马刷新缓冲区&#xff0c;\r不会刷新缓冲区 刷新的2个场景: 1 ~fflush 缓冲区中存在\r或\n --> \r fflush --> 不换行的\n) 2 ~ 文件关闭自动刷新缓冲区 倒计时小程序0-9 倒计时小程序0-99

PostgreSQL 可观测性最佳实践

简介 软件简述 PostgreSQL 是一种开源的关系型数据库管理系统 (RDBMS)&#xff0c;它提供了许多可观测性选项&#xff0c;以确保数据库的稳定性和可靠性。 可观测性 可观测性&#xff08;Observability&#xff09;是指对数据库状态和操作进行监控和记录&#xff0c;以便在…

中间继电器的文字符号和图形符号

中间继电器的文字符号和图形符号 中间继电器主要用途是当其他继电器触头数量或容量不够时&#xff0c;可借助中间继电器扩充触头数目或增大触头容量&#xff0c;起中间转换作用。将多个中间继电器相组合&#xff0c;还能构成各种逻辑运算电器或计数电器。 中间继电器文字符号…

C# WPF上位机开发(windows pad上的应用)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 大部分同学可能都认为c# wpf只能用在pc端。其实这是一种误解。c# wpf固然暂时只能运行在windows平台上面&#xff0c;但是windows平台不仅仅是电脑…

iconify图标集离线使用方案简介

1.需求描述 前端项目&#xff0c;技术栈使用Vue3Element Plus&#xff0c;参考了ruoyi-vue-pro项目与vue-element-plus-admin项目&#xff0c;封装了一个Icon组件&#xff0c;图标使用的是iconify,项目部署在内网环境&#xff0c;不能连接互联网&#xff0c;需要部署一套iconi…

Linux操作系统基础知识点

Linux是一种计算机操作系统&#xff0c;其内核由林纳斯本纳第克特托瓦兹&#xff08;Linus Benedict Torvalds&#xff09;于1991年首次发布。Linux操作系统通常与GNU套件一起使用&#xff0c;因此也被称为GNU/Linux。它是一种类UNIX的操作系统&#xff0c;设计为多用户、多任务…

【自定义磨砂动态背景】前端及pyqt6实现

如何实现一个自定义的磨砂动态背景呢&#xff1f; 这种效果看起来特别的高端&#xff0c;很新颖美观。 具体的效果可以看这里的演示&#xff1a;https://www.bilibili.com/video/BV1zj411H7wd/ 其实原理就是底层有多个多彩多边形在移动&#xff0c;然后再盖上一层模糊滤镜。 前…

React Router有几种模式?实现原理?

面试官&#xff1a;说说React Router有几种模式&#xff1f;实现原理&#xff1f; 一、是什么 在单页应用中&#xff0c;一个web项目只有一个html页面&#xff0c;一旦页面加载完成之后&#xff0c;就不用因为用户的操作而进行页面的重新加载或者跳转&#xff0c;其特性如下&a…

Windows系统配置pytorch环境,Jupyter notebook编辑器安装使用(深度学习本地篇)

如今现在好一点的笔记本都自带英伟达独立显卡&#xff0c;对于一些简单的深度学习项目&#xff0c;是不需要连接服务器的&#xff0c;甚至数据量不大的话&#xff0c;cpu也足够进行训练学习。我把电脑上一些以前的笔记整理一下&#xff0c;记录起来&#xff0c;方便自己35岁事业…

C++系列第九篇 数据类型下篇 - 复合类型(指针高级应用)

系列文章 C 系列 前篇 为什么学习C 及学习计划-CSDN博客 C 系列 第一篇 开发环境搭建&#xff08;WSL 方向&#xff09;-CSDN博客 C 系列 第二篇 你真的了解C吗&#xff1f;本篇带你走进C的世界-CSDN博客 C 系列 第三篇 C程序的基本结构-CSDN博客 C 系列 第四篇 C 数据类型…