回溯法——(1)装载问题(C语言讲解)

目录

一、装载问题

1.问题概括:

2.解决方案(思路):

 3.图片讲解(超详细):

4.代码分析:

二、算法改进:引入上界函数

1.问题概念:

2.图片讲解:

3.升级代码分析: 


一、装载问题

1.问题概括:

        有一批共n个集装箱要装上2艘载重量分别为c1和c1的轮船,其中集装箱i重量为wi,且

         装载问题要求确定是否有一个合理的装载方案可将这一批集装箱装上这2艘轮船。

如果有,找出一种装载方案。

2.解决方案(思路):

  1. 首先将第一艘轮船尽可能装满。
  2. 将剩余的集装箱装上第二艘轮船。

        将第一艘船尽可能装满,等价于选取全体集装箱的一个子集,使该子集中集装箱重量之和最接近c1。因此,装载问题等价于特殊的0-1背包问题

        由此可知,需要满足一下条件:

 其中,

 3.图片讲解(超详细):

        假设一艘船能装载货物的重量为9,货物有三个,重量w(weight)分别为6,3,1。并且要求第一艘船重量最大(max),不能超重。

讲解:       

        设定第一艘为c1,

        第一次在c1船上放置重量为6的货物,

                                此时c1已装入6,剩余3,

        第二次在继续向c1船上放置重量为3的货物,

                                此时c1已装入6+3=9,剩余0,

        第三次如过在继续向c1船上放置重量为1的货物,

                                此时c1船已装入6+3+1=10≥9,剩余-1,

        说明c1船超载了,也就是说,第三次重量为1的货物应该装载在第二艘船c2,第一艘不装。

        由此,我们将放入第一艘船的标为1,不放入第一艘船的标为0,构建二叉树,得到我们第一串存放方式的编码,110

        以此类推,得出其他可能,但我们需在代码中设置bestw用于存储最优解,也就是哪一个线路或者说是方案策略,可以使得该线路或者该方案策略得出的c1接近最大值max。

其实该方法可以总结为:

        从一条路往前走,能进则进,不能进则退回来,换一条路再试。

        这种走不通就退回再走的技术为回溯法。

4.代码分析:

/*cw:当前重量bestw:最佳重量x[]:当前调度bestx[]:最有调度c:容量w[]:货物重量
*///搜索第i层节点
void backtrack(int i) {//到达叶子节点if (i > n) {if (cw > bestw)return;}//搜索左子树if (cw + w[i] <= c) {cw += w[i];backtrack(i + 1);cw -= w[i];}//不行就去下一级继续backtrack(i+1);
}

        在函数backtrack中,当到达叶子节点(即i > n)时,会检查当前的总重量cw是否大于已知的最佳重量bestw。如果是,就返回;否则,继续搜索。

        在搜索左子树时,如果当前的总重量cw加上下一个物品的重量w[i]不超过背包的容量c,就将该物品加入当前调度,并递归地搜索下一个节点。在搜索右子树时,不将当前物品加入调度,而是直接递归地搜索下一个节点。

        这样,每次搜索左子树时,都会尝试将物品i加入调度,然后继续搜索下一个节点。如果在某个节点处,发现无法将物品i加入调度(即cw + w[i] > c),就会转而搜索右子树,即不将物品i加入调度,而是直接递归地搜索下一个节点。这种搜索方式保证了所有可能的调度都被尝试过了,从而可以找到最优解。


二、算法改进:引入上界函数

1.问题概念:

        设r是剩余集装箱的重量,即

定义上界函数为cw+r。若cw+r≤bestw,即当前重量+剩余集装箱重量比最佳重量还小,则可将当前结点的右子树减去,即不装的情况不用考虑。从而节省内存消耗以及代码计算时间。

还是上面那个例子:

        假设一艘船能装载货物的重量为9,货物有三个,重量w(weight)分别为6,3,1。并且要求第一艘船重量最大(max),不能超重。

2.图片讲解:

3.升级代码: 

/*cw:当前重量bestw:最佳重量x[]:当前调度bestx[]:最有调度c:容量w[]:货物重量
*/
//搜索第i层节点
void Backtrack(int i) {//如果到达叶子结点if (i > n) {if (cw > bestw) {for (int j = i; j <= n; j++) {bestx[j] = x[j];//更新最优解bestw = cw;}}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];
}

 

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

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

相关文章

【设计模式】工厂方法模式(Factory Method Pattern)

目录标题 工厂方法设计模式详解1. 介绍2. 结构3. 实现步骤3.1 创建抽象产品接口3.2 创建具体产品类3.3 创建抽象工厂接口3.4 创建具体工厂类3.5 客户端使用 4. 好处与优点5. 坏处与缺点6. 适用场景7. 总结 工厂方法设计模式详解 1. 介绍 工厂方法模式是一种创建型设计模式&am…

SpringCloud学习笔记(一)微服务介绍、服务拆分和RestTemplate远程调用、Eureka注册中心

文章目录 1 认识微服务1.1 单体架构1.2 分布式架构1.3 微服务1.4 SpringCloud1.5 总结 2 服务拆分与远程调用2.1 服务拆分原则2.2 服务拆分示例2.2.1 搭建项目2.2.2 创建数据库和表2.2.3 实现远程调用2.2.3.1 需求描述2.2.3.2 注册RestTemplate2.2.3.3 实现远程调用 2.2.4 提供…

strtok,perror,strerror函数·

strtok函数 strtok函数是C语言中的一个字符串函数&#xff0c;用于将一个字符串根据特定的分隔符拆分成多个子字符串。它的函数原型如下&#xff1a; char *strtok(char *str, const char *delim); 在这个函数中&#xff0c;str表示要进行拆分的字符串&#xff0c;delim表示…

Spark01 —— Spark基础

文章目录 Spark01 —— Spark基础一、为什么选择Spark&#xff1f;1.1 MapReduce编程模型的局限性1.2 Spark与MR的区别1.3 版本1.4 优势1.5 Spark其他知识1、多种运行模式2、技术栈3、spark-shell&#xff1a;Spark自带的交互式工具4、Spark服务 二、Spark的基础配置三、Spark实…

Spring-Mybatis-Xml管理(动态sql语句,sql语句复用)

目录 前置条件 动态SQL语句 动态删除数据 1.集合类型:数组 2.集合类型: List 型 SQL语句重用 说明 &#x1f9e8;前置条件 已经创建了实体类(这边举个例子) 实体类User表 表中的字段名User实体类的属性值id (bigint auto increment) 长整型 自动增长private Long iduser…

day17-day20_项目实战项目部署

万信金融 项目部署 目标&#xff1a; 理解DevOps概念 能够使用Docker Compose部署项目 理解持续集成的作用 会使用Jenkins进行持续集成 1 DevOps介绍 1.1 什么是DevOps DevOps是Development和Operations两个词的缩写&#xff0c;引用百度百科的定义&#xff1a; DevOps…

《C语言深度解剖》(10):数组指针、指针数组和数组指针数组

&#x1f921;博客主页&#xff1a;醉竺 &#x1f970;本文专栏&#xff1a;《C语言深度解剖》《精通C指针》 &#x1f63b;欢迎关注&#xff1a;感谢大家的点赞评论关注&#xff0c;祝您学有所成&#xff01; ✨✨&#x1f49c;&#x1f49b;想要学习更多C语言深度解剖点击专栏…

重学java 26.面向对象 内部类⭐

“别担心&#xff0c;你一定能如愿。” —— 24.4.29 1.什么时候使用内部类&#xff1a; 当一个事物的内部&#xff0c;还有一个部分需要完整的结构去描述&#xff0c;而内部的完整结构又只为外部事物提供服务&#xff0c;那么整个内部的完整结构最好使用内部类 比如&#xff1…

人工智能论文:BERT和GPT, GPT-2, GPT-3 的简明对比和主要区别

在BERT的论文里面&#xff1a; 2018.10 BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding&#xff0c;BERT已经解释了BERT&#xff0c;GPT&#xff0c;ELMo的区别。 *ELMo为双向RNN&#xff0c;请忽略。 主要区别&#xff1a; BERT使用的是…

49. 【Android教程】HTTP 使用详解

在你浏览互联网的时候&#xff0c;绝大多数的数据都是通过 HTTP 协议获取到的&#xff0c;也就是说如果你想要实现一个能上网的 App&#xff0c;那么就一定会和 HTTP 打上交道。当然 Android 发展到现在这么多年&#xff0c;已经有很多非常好用&#xff0c;功能非常完善的网络框…

信息系统项目管理师0078:安全系统(5信息系统工程—5.4安全工程—5.4.2安全系统)

点击查看专栏目录 文章目录 5.4.2安全系统1.安全机制2.安全服务3.安全技术5.4.2安全系统 信息安全保障系统一般简称为信息安全系统,它是“信息系统”的一个部分,用于保证“业务应用信息系统”正常运营。现在人们已经明确,要建立一个“信息系统”,就必须要建立一个或多个业务…

hive使用hplsql进行etl或其它数据加工

参照 https://cwiki.apache.org/confluence/pages/viewpage.action?pageId59690156 http://www.hplsql.org/doc Hive HPL/SQL&#xff0c;即Hive Hybrid Procedural SQL一个开源工具&#xff0c;它为hive实现了过程性的SQL功能&#xff0c;类似Oracle的PLSQL。从hive 2.0.0开…

RustGUI学习(iced)之小部件(四):如何使用单选框radio部件?

前言 本专栏是学习Rust的GUI库iced的合集&#xff0c;将介绍iced涉及的各个小部件分别介绍&#xff0c;最后会汇总为一个总的程序。 iced是RustGUI中比较强大的一个&#xff0c;目前处于发展中&#xff08;即版本可能会改变&#xff09;&#xff0c;本专栏基于版本0.12.1. 概述…

Python量化炒股的获取数据函数—get_concept()

查询股票所属的概念板块函数get_concept()&#xff0c;利用该函数可以查询一只或多只股票所属的概念板块&#xff0c;其语法格式如下&#xff1a; get_concept(security, dateNone)security&#xff1a;标的代码。类型为字符串&#xff0c;形式如‘000001.XSHE’&#xff0c;或…

k8s安装nginx Ingress超详细指南

在本全面的 Ingress 指南中&#xff0c;您将学习如何在 Kubernetes 上设置 Nginx Ingress控制器并使用 DNS 配置 Ingress。 目前有两种 Nginx Ingress 控制器。 kubernetes 社区的 Nginx Ingress 控制器Nginx Inc 开发的 Nginx Ingress 控制器 我们将使用 Kubernetes 社区 N…

使用QT完成如图的游戏登录界面 使用信号和槽完成密文明文密码转换,重置账号和密码,登录校验 详细代码在主页下载

头文件: #ifndef LOGINWIDGET_H #define LOGINWIDGET_H #include <QLineEdit> #include <QPushButton> #include <QWidget> class LoginWidget : public QWidget {Q_OBJECT public: LoginWidget(QWidget *parent = 0); ~LoginWidget(); public slots: …

【银角大王——Django课程——用户表的基本操作】

Django课程——用户表的基本操作 模板的继承用户管理用户列表展示新建用户Django组件原始方法【麻烦&#xff0c;太原始】form组件modelform组件 使用modelsform组件编写添加页面 模板的继承 &#xff08;1&#xff09;先写一个页面模板————这个案例中的模板基本上就是一个…

JAVA基础——集合框架(List与Set)

数据结构 什么是数据结构 数据结构就是用来装数据以及数据与之间关系的一种集合。如何把相关联的数据存储到计算机&#xff0c;为后续的分析提供有效的数据源&#xff0c;是数据结构产生的由来。数据结构就是计算机存储、组织数据的方式。好的数据结构&#xff0c;让我们做起事…

【统计推断】-01 抽样原理之(三)

文章目录 一、说明二、抽样分布三 均值抽样分布3.1 有限母体无放回抽样3.2 有限母体有放回抽样3.3 无限母体 四、比例抽样分布五、和差抽样分布 一、说明 上文中叙述母体和抽样的设计&#xff1b;以及抽样分布的概念&#xff0c;本篇将这种关系定量化&#xff0c;专门针对抽样的…

练习题(2024/4/29)

在深度优先遍历中&#xff1a;有三个顺序&#xff0c;前中后序遍历 这里前中后&#xff0c;其实指的就是中间节点的遍历顺序&#xff0c;只要记住 前中后序指的就是中间节点的位置就可以了。 如图 1二叉树的前序遍历 给你二叉树的根节点 root &#xff0c;返回它节点值的 前…