当前位置: 首页 > news >正文

【算法设计与分析】实验——二维0-1背包问题(算法分析题:算法思路),独立任务最优调度问题(算法实现题:实验过程,描述,小结)

说明:博主是大学生,有一门课是算法设计与分析,这是博主记录课程实验报告的内容,题目是老师给的,其他内容和代码均为原创,可以参考学习,转载和搬运需评论吱声并注明出处哦。

要求:3-1为算法分析题,写出主要的算法即可。3-2为算法实现题,要求写出:实验名称、实验过程描述(包括程序代码、测试用例、实验结果分析)、实验小结(包括实验过程中遇到的问题及体会)。

算法分析题3-1 二维0-1背包问题

给定n种物品和一背包。物品i的重量是wi ,体积是bi,其价值为vi,背包的容量为c,容积为d。问应如何选择装入背包中的物品,使得装入背包中物品的总价值最大?在选择装入背包的物品时,对每种物品i只能有两种选择,即装入背包和不装入背包。不能将物品i装入背包多次,也不能只装入部分的物品i。尝试设计一个解决此问题的动态规划算法,并分析算法的时间复杂性。

主要算法思路:

设计一个三位数组dp,存放的值dp[i][j][k]代表前i个物品已经安排好,背包重量为j,体积为k时已经放入的物品的总价值。初始值dp[0][j][k]为0;对于每个物品,有两种选择,选和不选,首先判断是否能放下背包中,如果能,判断放入后,减去重量和体积,加上价值,是否比当前价值大,如果大的话加入,小的话不加入。

时间复杂性分析:

算法实现利用了三层循环,时间复杂性为O(n*c*d).

# a存放所有物品信息(二维列表a[价值][重量][体积]),c背包容量,d容积,dp动态规划数组
def value_max(a, c, d):n = len(a)dp = [[[0 for _ in range(d + 1)] for _ in range(c + 1)] for _ in range(n + 1)]for i in range(1, n+1):  # 遍历每个物品for j in range(c + 1):  # 遍历所有可能的重量for k in range(d + 1):  # 遍历所有可能的体积if j >= a[i-1][1] and k >= a[i-1][2]:dp[i][j][k] = max(dp[i - 1][j][k],  # 不装入dp[i - 1][j - a[i-1][1]][k - a[i-1][2]] + a[i-1][0]  # 装入)else:dp[i][j][k] = dp[i - 1][j][k]return dp[n][c][d]  # 最大价值

算法实现题3-2 独立任务最优调度问题

问题描述:

用2台处理机A和B处理n个作业。设第i个作业交给机器A处理时需要时间ai,若由机器B来处理,则需要时间bi。由于各作业的特点和机器的性能关系,很可能对于某些i,有ai>=bi,而对于某些j, j≠i,有aj<bj。既不能将一个作业分开由2台机器处理,也没有一台机器能同时处理2个作业。
设计一个动态规划算法,使得这2台机器处理完这n个作业的时间最短(从任何一台机器开工到最后一台机器停工的总时间)。
研究一个实例: (a1,a2,a3,a4,a5,a6)=(2,5,7,10,5,2);(b1,b2,b3,b4,b5,b6)=(3,8,4,11,3,4)。 对于给定的2台处理机A 和B处理n 个作业,找出一个最优调度方案,使2台机器处理完这n个作业的时间最短。

编程任务:

对于给定的2台处理机A B处理n 个作业,找出一个最优调度方案,使2台机器处理

完这n 个作业的时间最短。

数据输入:

由文件input.txt提供输入数据。文件的第1行是1个正整数n, 表示要处理n个作业。接下来的2行中,每行有n 个正整数,分别表示处理机A 和B 处理第i 个作业需要的处理时间。

结果输出:

程序运行结束时,将计算出的最短处理时间输出到文件output.txt 中。

实验名称

独立任务最优调度问题

实验过程描述

程序代码

# 共有n个作业,a,b是机器处理作业需要时间的列表
# dp[i][j]表示处理前i个作业,机器A花费时间为j时,机器B的最小处理时间
def schedule(n, a, b):sum_a = sum(a)dp = [[float('inf')] * (sum_a + 1) for _ in range(n + 1)]dp[0][0] = 0for i in range(1, n + 1):for j in range(sum_a + 1):if j >= a[i - 1] and dp[i - 1][j - a[i - 1]] != float('inf'):dp[i][j] = dp[i - 1][j - a[i - 1]]  # A处理iif dp[i - 1][j] != float('inf'):dp[i][j] = min(dp[i][j], dp[i - 1][j] + b[i - 1])  # B处理imin_time = float('inf')# 所有可能的j中,max(j, dp[n][j])的最小值for j in range(sum_a + 1):if dp[n][j] != float('inf'):min_time = min(min_time, max(j, dp[n][j]))return min_time# 主程序
with open('input.txt', 'r') as f:n = int(f.readline())a = list(map(int, f.readline().split()))b = list(map(int, f.readline().split()))
result = schedule(n, a, b)
with open('output.txt', 'w') as f:f.write(str(result))
print("最短处理时间:", result)

测试用例

实验结果分析

本次实验实现了独立任务最优调度问题,两次测试用例分别对应的结果为49和192。

主要算法思路:

用动态规划设置一个dp数组,表示处理前i个作业,机器A花费时间为j时,机器B的最小处理时间(A,B也可以换顺序),然后下标从小到大遍历dp数组,对于每一个作业,有两种选择,a处理或者b处理,比较两者时间大小,选取花费时间较小的即可。而最终的结果,是对于所有a可能的处理时间中,也就是所有可能的j中,max(j, dp[n][j])的最小值。

时间复杂度分析:

双层循环,外层循环n次,内层循环sum_a+1次,所以时间复杂度为O(n*sum_a)

实验小结

问题

这道题在算法思路方面并没有特别大的问题,主要问题在于编写代码的过程中,如何去初始化dp数组,也就是语句

dp = [[float('inf')] * (sum_a + 1) for _ in range(n + 1)]
dp[0][0] = 0

首先考虑到dp数组一维大小要定义为机器A处理时间的最大值,也就是最坏情况当所有作业都由A来处理时;而数组的二维大小就是作业的总个数,这里的细节是遍历时要从1开始遍历,不然会出现数组下标错误。

体会

实践实现了动态规划算法的应用,主要语法学习点为使用float('inf')表示无穷大

http://www.lqws.cn/news/78679.html

相关文章:

  • 杂散的处理
  • 【存储基础】【VFS】inodedentrysuper_block以及它们之间的关系
  • C++哈希表:冲突解决与高效查找
  • Cesium使用primitive添加点线面(贴地)
  • Linux中的mysql备份与恢复
  • 查找和最小的K对数字
  • 软件开发项目管理工具选型及禅道开源版安装
  • 使用 MCP 将代理连接到 Elasticsearch 并对索引进行查询
  • UE5 创建2D角色帧动画学习笔记
  • HealthBench医疗AI评估基准:技术路径与核心价值深度分析(下)
  • 湖北理元理律所:企业债务重组中的“法律缓冲带”设计
  • 设计模式——备忘录设计模式(行为型)
  • 可视化大屏通用模板Axure原型设计案例
  • 谷粒商城-分布式微服务项目-高级篇[三]
  • DeepSeek 赋能车路协同:智能交通的破局与重构
  • Figma 与 Cursor 深度集成的完整解决方案
  • Windows不关防火墙,安全开放端口方法
  • 鸿蒙进阶——Mindspore Lite AI框架源码解读之模型加载详解(二)
  • Java设计模式之观察者模式详解
  • SystemVerilog—new函数的使用和误区
  • 【环境搭建】Java、Python、Nodejs等开发环境搭建
  • Fisher准则例题——给定类内散度矩阵和类样本均值
  • 2506js,活扩控件
  • 企业如何零基础建设网站?
  • 通俗理解“高内聚,低耦合”
  • 解锁 AI 大语言模型的“知识宝藏”:知识库的奥秘与优化之道
  • 项目管理进阶:56页大型IT项目管理实践经验分享【附全文阅读】
  • 学习STC51单片机25(芯片为STC89C52RCRC)
  • ESP32之Linux编译环境搭建流程
  • C++中实现随机数(超详细!​​​​​)