【算法分析与设计】回溯法(上)

news2024/11/24 12:51:04

目录

  • 一、学习要点
    • 1.1 回溯法
    • 1.2 问题的解空间
    • 1.3 0-1背包问题的解空间
    • 1.4 旅行售货员问题的解空间
    • 1.5 生成问题状态的基本方法
  • 二、回溯法的基本思想
  • 三、回溯算法的适用条件
  • 四、递归回溯
  • 五、迭代回溯
  • 六、子集树与排列树
  • 七、装载问题
  • 八、批处理作业调度问题


一、学习要点

  理解回溯法的深度优先搜索策略。
  掌握用回溯法解题的算法框架
  (1)递归回溯
  (2)迭代回溯
  (3)子集树算法框架
  (4)排列树算法框架

  通过应用范例学习回溯法的设计策略。
  (1)装载问题;
  (2)批处理作业调度;
  (3)符号三角形问题
  (4)n后问题;
  (5)0-1背包问题;
  (6)最大团问题;
  (7)图的m着色问题
  (8)旅行售货员问题
  (9)圆排列问题
  (10)电路板排列问题
  (11)连续邮资问题


1.1 回溯法

  有许多问题,当需要找出它的解集或者要求回答什么解是满足某些约束条件的最佳解时,往往要使用回溯法
  回溯法的基本做法是搜索,或是一种组织得井井有条的,能避免不必要搜索的穷举式搜索法。这种方法 适用于解一些组合数相当大的问题
  回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯否则,进入该子树,继续按深度优先策略搜索


1.2 问题的解空间

  问题的解向量:回溯法希望一个问题的解能够表示成一个n元式(x1,x2,…,xn)的形式。
  显约束对分量xi的取值限定
  隐约束为满足问题的解而对不同分量之间施加的约束
  解空间:对于问题的一个实例,解向量满足显式约束条件的所有多元组,构成了该实例的一个解空间

  注意:同一个问题可以有多种表示,有些表示方法更简单,所需表示的状态空间更小(存储量少,搜索方法简单)。
  n=3时的0-1背包问题用完全二叉树表示的解空间:
在这里插入图片描述


1.3 0-1背包问题的解空间

  问题的解空间应该至少包含问题的一个(最优)解
  对于n种可选择物品的0-1背包问题,其解空间由长度为n的0-1向量组成
  当n=3时,其解空间为{(0,0,0),(0,0,1),(0,1,0),(0,1,1),(1,0,0),(1,0,1),(1,1,0),(1,1,1)}
  解空间其实就是解的集合


1.4 旅行售货员问题的解空间

  问题:某售货员要到若干城市去推销商品,已知各城市之间的路程(旅费)。他要选择一条从驻地出发,经过每个城市一遍,然后回到驻地的路线,使总的路程(总旅费)最小。
在这里插入图片描述
在这里插入图片描述


1.5 生成问题状态的基本方法

  白结点:未被访问到的结点
  灰结点:一个自身已生成但其儿子还没有全部生成的节点称做灰结点
  黑结点:一个所有儿子已经产生的结点称做黑结点
  深度优先的问题状态生成法:如果对一个扩展结点R,一旦产生了它的一个儿子C,就把C当做新的扩展结点。在完成对子树C(以C为根的子树)的穷尽搜索之后,将R重新变成扩展结点,继续生成R的下一个儿子(如果存在)。
  宽度优先的问题状态生成法:在一个扩展结点变成黑结点之前,它一直是扩展结点。
  回溯法为了避免生成那些不可能产生最佳解的问题状态,要不断地利用限界函数(bounding function)来处死那些实际上不可能产生所需解的活结点,以减少问题的计算量。具有限界函数的深度优先生成法称为回溯法


二、回溯法的基本思想

  (1)针对所给问题,定义问题的解空间
  (2)确定易于搜索的解空间结构
  (3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索
  常用剪枝函数
  用约束函数在扩展结点处剪去不满足约束的子树
  用限界函数剪去得不到最优解的子树

  用回溯法解题的一个显著特征是在搜索过程中动态产生问题的解空间在任何时刻,算法只保存从根结点到当前扩展结点的路径。如果解空间树中从根结点到叶结点的最长路径的长度为h(n),则回溯法所需的计算空间通常为O(h(n))。而显式地存储整个解空间则需要O(2h(n))或O(h(n)!)内存空间。


三、回溯算法的适用条件

  在结点<x1,x2,…,xk>处P(x1,x2,…,xk)为真。即向量<x1,x2,…,xk>满足某个性质,则有P(x1,x2,…,xk+1)-> P(x1,x2,…,xk) 0<k<n。称之为多米诺性质
  ┐ P(x1,x2,…,xk) ->┐ P(x1,x2,…,xk+1) 0<k<n
  k维向量不满足约束条件,扩张向量到k+1维仍旧不满足,才可以进行回溯


四、递归回溯

  回溯法对解空间作深度优先搜索,因此,在一般情况下用递归方法实现回溯法

void backtrack (int t)
{
       if (t>n) output(x);
       else
         for (int i=f(n,t);i<=g(n,t);i++) {
           x[t]=h(i);
           if (constraint(t)&&bound(t)) backtrack(t+1);
           }
}

五、迭代回溯

  采用 树的非递归深度优先遍历算法,可将回溯法表示为一个非递归迭代过程

void iterativeBacktrack ()
{
  int t=1;
  while (t>0) {
    if (f(n,t)<=g(n,t)) 
      for (int i=f(n,t);i<=g(n,t);i++) {
        x[t]=h(i);
        if (constraint(t)&&bound(t)) {
          if (solution(t)) output(x);
          else t++;}
        }
    else t--;
    }
}

六、子集树与排列树

  当所给问题是从n个元素的集合S中找出满足某种性质的子集时,相应的解空间树称为子集树(2n)。
  当所给问题是确定n个元素满足某种性质的排列时,相应的解空间树称为排列树(n!)。
在这里插入图片描述
  遍历子集树需O(2n)计算时间

void backtrack (int t)
{
  if (t>n) output(x);
    else
      for (int i=0;i<=1;i++) {
        x[t]=i;
        if (legal(t)) backtrack(t+1);
      }
}

在这里插入图片描述
  遍历排列树需要O(n!)计算时间

void backtrack (int t)
{
  if (t>n) output(x);
    else
      for (int i=t;i<=n;i++) {
        swap(x[t], x[i]);
        if (legal(t)) backtrack(t+1);
        swap(x[t], x[i]);
      }
} 

七、装载问题

  有一批共n个集装箱要装上2艘载重量分别为c1和c2的轮船,其中集装箱i的重量为wi,且在这里插入图片描述
  装载问题要求确定是否有一个合理的装载方案可将这个集装箱装上这2艘轮船。如果有,找出一种装载方案。
  将第一艘轮船尽可能装满等价于选取全体集装箱的一个子集,使该子集中集装箱重量之和最接近。由此可知,装载问题等价于以下特殊的0-1背包问题。
在这里插入图片描述
  用回溯法设计解装载问题的O(2n)计算时间算法。在某些情况下该算法优于动态规划算法

  当n=3,c1=c2=50,且w=[10,40,40]
  如果w=[20,40,40]
  最优装载方案
  (1)首先将第一艘轮船尽可能装满
  (2)将剩余的集装箱装上第二艘轮船

  解空间:子集树
  可行性约束函数(选择当前元素):
  上界函数(不选择当前元素)
  当前载重量cw+剩余集装箱的重量r≤当前最优载重量bestw

void backtrack (int i)
   {// 搜索第i层结点
      if (i > n)  // 到达叶结点
      更新最优解bestx,bestw;return;
      r -= w[i];
      if (cw + w[i] <= c) {// 搜索左子树
         x[i] = 1;
         cw += w[i];
         backtrack(i + 1);
         cw -= w[i];      }
      if (cw + r > bestw)  {
         x[i] = 0;  // 搜索右子树
         backtrack(i + 1);      }
      r += w[i];
   }

在这里插入图片描述


八、批处理作业调度问题

  n个作业{1, 2, …, n}要在两台机器上处理,每个作业必须先由机器1处理,然后再由机器2处理,机器1处理作业i所需时间为ai,机器2处理作业i所需时间为bi(1≤i≤n),批处理作业调度问题要求确定这n个作业的最优处理顺序,使得从第1个作业在机器1上处理开始,到最后一个作业在机器2上处理结束所需时间最少。
  显然,批处理作业的一个最优调度应使机器1没有空闲时间,且机器2的空闲时间最小。可以证明,存在一个最优作业调度使得在机器1和机器2上作业以相同次序完成

  例:三个作业{1, 2, 3},这三个作业在机器1上所需的处理时间为(2, 3, 2),在机器2上所需的处理时间为(1, 1, 3),则最佳调度方案是(1, 3, 2)、(3, 1, 2)和(3, 2, 1),其完成时间为8。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
  解空间:排列树

void Flowshop::Backtrack(int i)
{
   if (i > n) {
       for (int j = 1; j <= n; j++)
         bestx[j] = x[j];
       bestf = f;
       }
   else
      for (int j = i; j <= n; j++) {
         f1+=M[x[j]][1];
         f2[i]=((f2[i-1]>f1)?f2[i-1]:f1)+M[x[j]][2];
         f+=f2[i];
         if (f < bestf) {
            Swap(x[i], x[j]);
            Backtrack(i+1);
            Swap(x[i], x[j]);
            }
         f1- =M[x[j]][1];
         f- =f2[i];
         }
}

在这里插入图片描述

class Flowshop {
   friend Flow(int**, int, int []);
   private:
      void Backtrack(int i);
      int  **M,    // 各作业所需的处理时间
              *x,     // 当前作业调度
        *bestx,    // 当前最优作业调度
             *f2,    // 机器2完成处理时间
              f1,    // 机器1完成处理时间
               f,     // 完成时间和
         bestf,    // 当前最优值
               n;   // 作业数}; 

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

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

相关文章

Scala第十一章节

Scala第十一章节 1.模式匹配 2. Option 类型 3.偏函数 4.正则表达式 5.异常处理 6.提取器 7.案例&#xff1a;随机职业 scala总目录 文档资料下载

大数据Flink(九十五):DML:Window TopN

文章目录 DML:Window TopN DML:Window TopN Window TopN 定义(支持 Streaming):Window TopN 是一种特殊的 TopN,它的返回结果是每一个窗口内的 N 个最小值或者最大值。 应用场景

【C语言】模拟实现strstr

strstr这个库函数看到这个名字大概率猜不到这是什么函数&#xff0c; 但经过学习就可以很好的认识到这个函数 目录 介绍&#xff1a;模拟实现&#xff1a;思路&#xff1a;代码实现&#xff1a; 介绍&#xff1a; 可以看到此函数是用来寻找一个字符串中是否含有另一个字符串 代…

云安全之HTTP协议介绍补充

HTTP是一个基于TCP/IP通信协议来传递数据的协议&#xff0c;传输的数据类型为HTML文件、图片文件、查询结果等。HTTP协议一般用于B/S架构。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。 URI、URL、URN HTTP使用统一资源标识符(Uniform Resource ldentif…

WebSocket实战之二协议分析

一、前言 上一篇 WebSocket实战之一 讲了WebSocket一个极简例子和基础的API的介绍&#xff0c;这一篇来分析一下WebSocket的协议&#xff0c;学习网络协议最好的方式就是抓包分析一下什么就都明白了。 二、WebSocket协议 本想盗一张网络图&#xff0c;后来想想不太好&#x…

ImportSelector使用详解

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl ImportSelector概述 利用Import和ImportSelector可将组件批量添加至IoC容器 ImportSelector案例 在此&#xff0c;介绍ImportSelector使用案例。 定义ImportSelector S…

Kotlin前置检测判断check,require,requireNotNull

Kotlin前置检测判断check&#xff0c;require&#xff0c;requireNotNull &#xff08;1&#xff09;check fun main(args: Array<String>) {val b falsecheck(b) {println("check $b")}println("end") } check监测到值非真时候&#xff0c;抛出一…

国庆作业day5

应用层&#xff1a;提供用户与网络应用程序之间的接口。表示层&#xff1a;负责数据的格式转换、加密和解密。会话层&#xff1a;负责建立、管理和终止会话。它提供会话控制和同步&#xff0c;允许应用程序之间建立连接和交换数据。传输层&#xff1a;提供端到端的连接。网络层…

【ppt技巧】给ppt文件设置带有密码的只读模式

有没有同学&#xff0c;想要给PPT文件设置修改权限&#xff0c;却没有找到功能&#xff0c;给PPT文件设置只读模式&#xff0c;没有密码设置的&#xff1f;今天给大家分享给PPT文件设置带有密码的只读模式&#xff08;修改权限&#xff09;。 打开PPT文件之后&#xff0c;将PP…

数据结构与算法课后题-第三章(顺序队和链队)

#include <iostream> //引入头文件 using namespace std;typedef int Elemtype;#define Maxsize 5 #define ERROR 0 #define OK 1typedef struct {Elemtype data[Maxsize];int front, rear;int tag; }SqQueue;void InitQueue(SqQueue& Q) //初始化队列 {Q.rear …

WebSocket实战之一

一、前言 2017年做股票软件开始关注WebSoocket技术&#xff0c;不过当时客户端是Native采用的网络通讯框架是Netty&#xff0c;这次做收银台项目决定把WebSocket技术实践一把&#xff0c;主要应用于实时销量大盘数据展示以及消息系统提醒功能等。 注&#xff1a;一个技术点尽…

10.4号作业

Qt实现客户端搭建的代码和现象 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpSocket> #include <QMessageBox>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJ…

嵌入式Linux应用开发-基础知识-第十九章驱动程序基石④

嵌入式Linux应用开发-基础知识-第十九章驱动程序基石④ 第十九章 驱动程序基石④19.7 工作队列19.7.1 内核函数19.7.1.1 定义 work19.7.1.2 使用 work&#xff1a;schedule_work19.7.1.3 其他函数 19.7.2 编程、上机19.7.3 内部机制19.7.3.1 Linux 2.x的工作队列创建过程19.7.3…

嵌入式Linux应用开发-基础知识-第十九章驱动程序基石⑤

嵌入式Linux应用开发-基础知识-第十九章驱动程序基石⑤ 第十九章 驱动程序基石⑤19.9 mmap19.9.1 内存映射现象与数据结构19.9.2 ARM架构内存映射简介19.9.2.1 一级页表映射过程19.9.2.2 二级页表映射过程 19.9.3 怎么给APP新建一块内存映射19.9.3.1 mmap调用过程19.9.3.2 cach…

傅里叶系列 P1 的定价选项

如果您想了解更多信息&#xff0c;请查看第 2 部分和第 3 部分。 一、说明 这是第一篇文章&#xff0c;我将帮助您获得如何使用这个新的强大工具来解决金融中的半分析问题并取代您的蒙特卡洛方法的直觉。 我们都知道并喜欢蒙特卡洛数字积分方法&#xff0c;但是如果我告诉你你可…

InnoDB索引机制

导学&#xff1a;索引什么时候失效&#xff1f;为什么类型转换索引会失效&#xff1f;不满足最左匹配原则&#xff1f; 我们都知道&#xff0c;MySQL它主要有2大模快组成&#xff0c;第一块就是我们的MySQL服务&#xff0c;里面包含了像连接管理、解析器、预处理、优化器、执行…

数据分析:人工智能篇

文章目录 第三章 数据可视化库matplotlib3.1 matplotlib基本绘图操作3.2 plot的线条和颜色3.3 条形图分析3.4 箱型图分析3.5 直方图分析3.6 散点图分析3.7 图表的美化 第四章 数据预测库Sklearn4.1 sklearn预测未来4.2 回归数据的预测4.2.1 回归数据的切分4.2.2 线性回归数据模…

【vue3】shallowReactive与shallowRef;readonly与shallowReadonly;toRaw与markRaw

假期第六篇&#xff0c;对于基础的知识点&#xff0c;我感觉自己还是很薄弱的。 趁着假期&#xff0c;再去复习一遍 1、shallowReactive与shallowRef shallowReactive&#xff1a;只处理对象最外层属性的响应式&#xff08;浅响应式&#xff09; shallowRef&#xff1a;只处理…

2023 彩虹全新 SUP 模板,卡卡云模板修复版

2023 彩虹全新 SUP 模板&#xff0c;卡卡云模板&#xff0c;首页美化&#xff0c;登陆页美化&#xff0c;修复了 PC 端购物车页面显示不正常的问题。 使用教程 将这俩个数据库文件导入数据库&#xff1b; 其他的直接导入网站根目录覆盖就好&#xff1b; 若首页显示不正常&a…

华为云云耀云服务器L实例评测|部署在线轻量级备忘录 memos

华为云云耀云服务器L实例评测&#xff5c;部署在线轻量级备忘录 memos 一、云耀云服务器L实例介绍1.1 云服务器介绍1.2 产品优势1.3 应用场景1.4 支持镜像 二、云耀云服务器L实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 memos3.1 memos介绍3.2 Docker 环境搭建…