【算法设计与分析】实验7:复杂装载及0/1背包问题的回溯法设计与求解

目录

一、实验目的

二、实验环境

三、实验内容

四、核心代码

五、记录与处理

六、思考与总结

七、完整报告和成果文件提取链接

一、实验目的

        针对复杂装载问题、及0/1背包问题开展分析、建模、评价,算法设计与优化,并进行编码实践。

        理解复杂装载问题及0/1背包问题的回溯法求解策略,能够对比分析与动态规划求解复杂装载问题的策略差异;能够根据具体的问题进行解空间树的构造及剪枝函数设计;针对如上两个问题利用回溯法进行设计求解,并进行对比两个问题求解时的异同。并利用JAVA/C/C++等编程语言将算法转换为对应的程序上机运行(语言自选)。

二、实验环境

        1、机房电脑  Window10

        2、Eclipse /DEVC++等

三、实验内容

实验要求:

1、掌握回溯法进行问题分析及建模的过程;

2、复杂装载、及0/1背包问题能够利用回溯法开展算法设计与优化;

(1)复杂装载问题背景:指定两艘船容量C1,C2,给定n个货物,各物品重量wi已知。请问是否可以成功装入两艘船,及如何选择物品分别装入两艘船?

(2)0/1背包问题背景:指定背包容量C,给定n个商品,各商品重量wi、价值vi已知。如何选择商品,使得装入背包的价值最大?

3、能够对上述问题的回溯法进行时间复杂性分析,并与动态规划进行对比。

【回溯法原理】

        回溯法是一种暴力搜索方法,它将问题的解表示为n元组(x1, x2, …, xn)的形式。其核心在于逐步构建一个解空间,过程中涉及选择、判断及必要的回退步骤,直至找到问题的解或确认无解。这种求解思路类似于逐步探索的过程,一旦当前路径不满足求解条件,便“回溯”以尝试其他路径。

       解决一个问题的所有可能的决策序列就是解空间。

       对于回溯法解决的问题而言,它的解空间一般用树或图的形式来组织,即为解空间树,树的每一个结点确定每个问题的一个状态。树的根结点代表初始状态,以下每一层代表所作出的选择。

       由于回溯法解决的问题较为冗杂,情况复杂,所以用回溯法搜索解空间时,通常采用两种策略避免无效搜索,提高回溯的搜索效率。

实验原理:

1、针对复杂装载背包问题,如何利用回溯法进行算法设计

【装载方案】

(1)首先将第一艘轮船尽可能装满;

(2)然后将剩余的集装箱装在第二艘轮船上;

将第一艘轮船尽可能装满等价于选取全体集装箱的一个子集,在承载范围内,使该子集中集装箱重量之和最大。

复杂装载问题的解空间是一个子集树

【求解思路】

(1) 将尽可能多的集装箱装到第一艘船上

(2) 约束条件判断:cw + w[i] <= c,判断当前路径是否可以装载当前集装箱 i 而不超过船的最大承载能力 c

(3) 剪枝函数(限界条件):cw + r >bestw,判断当前路径是否有可能超过已知的最佳装载重量 bestw。

(4) 终止条件判断:当i>n时,说明已经遍历到叶子节点,此时判断cw > bestw,这个条件的作用是判断当前路径的装载重量 cw 是否超过了已知的最佳装载重量 bestw,如果满足则需要更新 bestw 为当前的装载重量 cw。

利用回溯法求解时:在最坏情况下,每个集装箱都有两个选择(装或不装),因此递归树的分支因子为 2。因此,递归树的最大深度为 n,每层最多有两个分支。最坏情况时间复杂度是O( ),剪枝策略的存在,会使实际运行时间通常会低于这个值,回溯法的空间复杂度为 O(n)

采用动态规划算法时,时间复杂度为动态规划算法O(nc) ,最优空间复杂度为O(c)

 一般情况下使用动态规划算法解决复杂装载问题的时间复杂度更优。

2、针对0/1背包问题,如何利用回溯法进行算法设计

【装载方案】

背包容量限制:每次选择物品时,必须确保当前背包中的物品总重量不超过背包容量 c。

物品选择限制:每个物品只能选择一次(0/1背包问题)。

最优解要求:在所有满足约束条件的解中,选择总价值最大的解。

【求解思路】

(1) 将尽可能多的价值高的装到背包中

(2) 约束条件判断:cw + w[i] <= c,该条件用于判断当前物品是否可以被选择。

(3) 剪枝函数(限界条件):剪枝函数 bound 用于计算当前解的上界,以决定是否继续搜索某个分支。cp+rp>bestp

(4) 终止条件判断:条件:i > n,当所有物品都已经考虑完毕时, i 超过物品数量 n时,检查当前解的价值 cp 是否大于已知的最佳价值 bestp。如果当前解更好,则更新最佳价值 bestp 并记录当前解 bestx。

对于0/1背包问题,回溯法方法求解时,计算上界需要O(n)时间,在最坏情况下有O( )个右儿子结点需要计算上界,所以时间复杂度为O( ),回溯法求解的空间复杂度为O(n)。

采用动态规划算法时,时间复杂度为O(nc) ,最优空间复杂度为O(c)

一般情况下使用动态规划算法解决0/1背包问题的时间复杂度更优。

3、针对同一问题,对比动态规划及回溯法求解的算法复杂度。

1.利用回溯法求解时:在最坏情况下,每个集装箱都有两个选择(装或不装),因此递归树的分支因子为 2。因此,递归树的最大深度为 n,每层最多有两个分支。最坏情况时间复杂度是O(2n ),剪枝函数会使实际运行时间通常会低于这个值,回溯法求解的空间复杂度为O(n)。

采用动态规划算法时,时间复杂度为O(nc) , 最优空间复杂度为O(c)

       一般情况下使用动态规划算法解决复杂装载问题的时间复杂度更优。

对于0/1背包问题,回溯法方法求解时,计算上界需要O(n)时间,在最坏情况下有O(2n )个右儿子结点需要计算上界,所以时间复杂度为O(n2n ),回溯法求解的空间复杂度为O(n)。

采用动态规划算法时,时间复杂度为O(nc) ,最优空间复杂度为O(c)

一般情况下使用动态规划算法解决0/1背包问题的时间复杂度更优。

四、核心代码

// 回溯函数,用于搜索所有可能的解
void backtrack(int i) {if (i > n) { // 如果已经考虑完所有物品if (cp > bestp) { // 如果当前价值大于已知最佳价值bestp = cp; // 更新最佳价值for (int j = 1; j <= n; j++) {bestx[j] = x[j]; // 记录最佳解}}return;}// 搜索左子树:选择当前物品if (cw + w[i] <= c) {x[i] = 1; // 标记选择当前物品cw += w[i]; // 更新当前重量cp += p[i]; // 更新当前价值backtrack(i + 1); // 递归处理下一个物品cw -= w[i]; // 回溯,恢复当前重量cp -= p[i]; // 回溯,恢复当前价值}// 搜索右子树:不选择当前物品if (bound(i + 1) > bestp) { // 只有当上界大于已知最佳价值时才继续搜索x[i] = 0; // 标记不选择当前物品backtrack(i + 1); // 递归处理下一个物品}
}
void backtrack(int i) {        //搜索深度为i的结点 if (i > n) {            // 如果所有货物都考虑完毕if (cw1 + cw2 > bestw) {    // 如果当前装载的总重量大于已知的最优解bestw = cw1 + cw2;        // 更新最优解的重量for (int j = 0; j <= n; ++j) {bestx[j] = x[j];    // 保存当前的装载方案}}return;}// 尝试将第i个物品放入第一艘船if (cw1 + w[i] <= C1 && cw1 + r1 > bestw) {x[i] = 1;cw1 += w[i];     // 更新第一艘船的装载重量r1 -= w[i];        // 更新剩余重量backtrack(i + 1);cw1 -= w[i];    // 回溯,恢复状态r1 += w[i];}
}

五、记录与处理

1、复杂装载问题实验数据及结果分析。

当输入C1=50,C2=50,w={10,40,40}时,所有货物都装进去了,最优装载量为90

2、0/1背包问题实验数据及结果分析。

六、思考与总结

通过本次实验,我对回溯法有了更深刻的理解。回溯法通过递归的方式,逐步构建问题的解空间,并在搜索过程中使用剪枝函数来避免无效搜索,从而提高搜索效率。这种方法在解决组合优化问题时非常有效,尤其是在解决解空间较小或可以通过剪枝显著减少搜索空间的一类问题时。

七、完整报告和成果文件提取链接

完整可运行代码以及相关实验报告以下链接可获取:
链接: https://pan.baidu.com/s/1iss6-C2nxZQGkEpo-WDn0A?pwd=g5cg 提取码: g5cg 

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

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

相关文章

oracle: 多表查询之联合查询[交集intersect, 并集union,差集minus]

把多个查询结果上下合并, 即, 通过操作符将多个 SELECT 语句的结果集合并为一个结果集。虽然联合查询通常用于从多个表中检索数据&#xff0c;但它也可以用于从同一个表中检索不同的数据集。 联合查询: 交集,并集,差集 默认的排序规则通常是基于查询结果集中的列的自然顺序。…

增删改查(CRUD)操作

文章目录 MySQL系列&#xff1a;1.CRUD简介2.Create(创建)2.1单行数据全列插入2.2 单行数据指定插入2.3 多⾏数据指定列插⼊ 3.Retrieve(读取)3.1 Select查询3.1.1 全列查询3.1.2 指定列查询3.1.3 查询字段为表达式&#xff08;都是临时表不会对原有表数据产生影响&#xff09;…

早期车主告诉后来者,很后悔买电车,一辈子都被车企拿捏了

从2015年开始大力发展电车&#xff0c;至今已有快10年了&#xff0c;头几批车主或是已换车&#xff0c;或是准备换车&#xff0c;他们用车这么多年的困扰以及换车的麻烦&#xff0c;却告诉准备买电车的消费者&#xff0c;电车没有媒体宣传的那么好&#xff0c;买了电车基本上一…

架构技能(四):需求分析

需求分析&#xff0c;即分析需求&#xff0c;分析软件用户需要解决的问题。 需求分析的下一环节是软件的整体架构设计&#xff0c;需求是输入&#xff0c;架构是输出&#xff0c;需求决定了架构。 决定架构的是软件的所有需求吗&#xff1f;肯定不是&#xff0c;真正决定架构…

H264原始码流格式分析

1.H264码流结构组成 H.264裸码流&#xff08;Raw Bitstream&#xff09;数据主要由一系列的NALU&#xff08;网络抽象层单元&#xff09;组成。每个NALU包含一个NAL头和一个RBSP&#xff08;原始字节序列载荷&#xff09;。 1.1 H.264码流层次 H.264码流的结构可以分为两个层…

pytorch生成对抗网络

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 生成对抗网络&#xff08;GAN&#xff0c;Generative Adversarial Network&#xff09;是一种深度学习模型&#xff0c;由两个神经网络组成&#xff1a;生成器&#xff08;Generator&#xff09;和判别器&#xff0…

AIGC技术中常提到的 “嵌入转换到同一个向量空间中”该如何理解

在AIGC&#xff08;人工智能生成内容&#xff09;技术中&#xff0c;“嵌入转换到同一个向量空间中”是一个核心概念&#xff0c;其主要目的是将不同类型的输入数据&#xff08;如文本、图像、音频等&#xff09;映射到一个统一的连续向量空间中&#xff0c;从而实现数据之间的…

芯片AI深度实战:给vim装上AI

系列文章&#xff1a; 芯片AI深度实战&#xff1a;私有模型deep seek r1&#xff0c;必会ollama-CSDN博客 芯片AI深度实战&#xff1a;自己的AI&#xff0c;必会LangChain-CSDN博客 芯片AI深度实战&#xff1a;给vim装上AI-CSDN博客 芯片AI深度实战&#xff1a;火的编程AI&…

汽车中控屏HMI界面,安全和便捷是设计的两大准则。

在汽车智能化的浪潮中&#xff0c;汽车中控屏 HMI&#xff08;Human - Machine Interface&#xff0c;人机交互界面&#xff09;界面已成为车辆与驾驶者沟通的关键桥梁。它不仅集成了众多车辆功能的控制&#xff0c;还承担着信息展示与交互的重任。而在其设计过程中&#xff0c…

书生大模型实战营3

文章目录 L0——入门岛git基础Git 是什么&#xff1f;Git 中的一些基本概念工作区、暂存区和 Git 仓库区文件状态分支主要功能 Git 平台介绍GitHubGitLabGitee Git 下载配置验证下载 Git配置 Git验证 Git配置 Git常用操作Git简易入门四部曲Git其他指令 闯关任务任务1: 破冰活动…

(9)下:学习与验证 linux 里的 epoll 对象里的 EPOLLIN、 EPOLLHUP 与 EPOLLRDHUP 的不同。小例子的实验

&#xff08;4&#xff09;本实验代码的蓝本&#xff0c;是伊圣雨老师里的课本里的代码&#xff0c;略加改动而来的。 以下是 服务器端的代码&#xff1a; 每当收到客户端的报文时&#xff0c;就测试一下对应的 epoll 事件里的事件标志&#xff0c;不读取报文内容&#xff0c;…

Janus-Pro 论文解读:DeepSeek 如何重塑多模态技术格局

Janus-Pro&#xff1a;多模态领域的璀璨新星——技术解读与深度剖析 一、引言 在人工智能的浩瀚星空中&#xff0c;多模态理解与生成模型犹如耀眼的星座&#xff0c;不断推动着技术边界的拓展。Janus-Pro作为这一领域的新兴力量&#xff0c;以其卓越的性能和创新的架构&#x…

好用的翻译工具

最近看到个好用的翻译工具&#xff0c;叫沉浸式翻译 沉浸式翻译 - 双语对照网页翻译插件 | PDF翻译 | 视频字幕翻译 我下载的是谷歌插件 点击下载插件会跳转到使用文档&#xff0c;跟着一步步操作即可 翻译的效果&#xff0c;我这里用的是免费版的&#xff0c;如果需要加强&…

信息学奥赛一本通 ybt 1608:【 例 3】任务安排 3 | 洛谷 P5785 [SDOI2012] 任务安排

【题目链接】 ybt 1608&#xff1a;【 例 3】任务安排 3 洛谷 P5785 [SDOI2012] 任务安排 【题目考点】 1. 动态规划&#xff1a;斜率优化动规 2. 单调队列 3. 二分答案 【解题思路】 与本题题面相同但问题规模不同的题目&#xff1a; 信息学奥赛一本通 1607&#xff1a…

LabVIEW无线齿轮监测系统

本案例介绍了基于LabVIEW的无线齿轮监测系统设计。该系统利用LabVIEW编程语言和改进的天牛须算法优化支持向量机&#xff0c;实现了无线齿轮故障监测。通过LabVIEW软件和相关硬件&#xff0c;可以实现对齿轮箱振动信号的采集、传输和故障识别&#xff0c;集远程采集、数据库存储…

Doki Doki Mods Maker小指南

-*- 做都做了&#xff0c;那就做到底吧。 -*- 前言&#xff1a; 项目的话&#xff0c;在莫盘里&#xff0c;在贴吧原帖下我有发具体地址。 这里是Doki Doki Mods Maker&#xff0c;是用来做DDLC Mods的小工具。 说是“Mods”&#xff0c;实则不然&#xff0c;这个是我从零仿…

Node.js——body-parser、防盗链、路由模块化、express-generator应用生成器

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

三、js笔记

(一)JavaScript概述 1、发展历史 ScriptEase.(客户端执行的语言):1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEase.(客户端执行的语言)Javascript:Netscape(网景)接收Nombas的理念,(Brendan Eich)在其Netscape Navigat…

JavaScript作用域详解

前言 作用域是JavaScript中一个重要的概念&#xff0c;它决定了变量和函数在代码中的可访问性和可见性。了解JavaScript的作用域对于编写高效、可维护的代码至关重要。本文将深入介绍JavaScript作用域相关的知识点&#xff0c;其中包括作用域类型&#xff0c;作用域链&#xff…

如何使用SliverList组件

文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了沉浸式状态栏相关的内容&#xff0c;本章回中将介绍SliverList组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1 概念介绍 我们在这里介绍的SliverList组件是一种列表类组件&#xff0c;类似我们之前介…