动态规划算法-以中学排班管理系统为例

1.动态规划算法介绍 

1.算法思路

动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。具体的动态规划算法多种多样,但它们具有相同的填表格式。

2.代码介绍

/private static boolean foundOptimal = false; // 用于全局控制是否找到// 优化课程安排,使用递归模拟动态规划过程private static void optimizeCourseScheduling(Scanner scanner, CourseService courseService) {System.out.print("输入可用教室数量:");int capacity = scanner.nextInt(); // 用户输入教室的容量scanner.nextLine();List<CourseEntity> courses = courseService.getAllCourses(); // 获取所有课程int n = courses.size(); // 课程总数int[] weights = new int[n]; // 每个课程占用的教室数量int[] values = new int[n]; // 每个课程的价值,这里使用教师ID// 为每门课程分配教师ID和教室资源System.out.println("正在为每门课程分配教师ID和教室资源...");for (int i = 0; i < n; i++) {weights[i] = 1; // 假设每个课程占用一个教室values[i] = courses.get(i).getTeacherId(); // 教师ID作为课程的价值}int maxValue = knapsack(0, weights, values, capacity, n);System.out.println("在可用教室数量为 " + capacity + " 的情况下,最大化的课程安排价值为:" + maxValue);// 初始化标记数组,所有课程初始为未选择boolean[] selected = new boolean[n];foundOptimal = false; // 重置全局变量printSelectedCourses(0, weights, values, capacity, n, selected, maxValue);if (!foundOptimal) {System.out.println("未找到符合条件的课程安排。");}}// 递归函数模拟动态规划解决背包问题
// 递归的深度为课程数量n,每层递归的复杂度与教室容量有关private static int knapsack(int index, int[] weights, int[] values, int capacity, int n) {// 基本情况:没有课程可选或背包容量为0if (index == n || capacity == 0) {return 0;}// 如果当前课程的重量大于背包容量,则不能选择该课程if (weights[index] > capacity) {return knapsack(index + 1, weights, values, capacity, n);}// 递归选择:选择包含当前课程或不包含当前课程的最大价值return Math.max(knapsack(index + 1, weights, values, capacity, n), // 不选择当前课程values[index] + knapsack(index + 1, weights, values, capacity - weights[index], n) // 选择当前课程);}// 递归回溯函数,意图是打印出被选中的课程和教师IDprivate static boolean printSelectedCourses(int index, int[] weights, int[] values, int currentCapacity, int n, boolean[] selected, int maxValue) {if (foundOptimal) {return true; // 如果已经找到最优解,直接返回}if (index == n) {int currentValue = 0;for (int i = 0; i < n; i++) {if (selected[i]) {currentValue += values[i];}}if (currentCapacity == 0 && currentValue == maxValue) {// 打印当前选择的课程for (int i = 0; i < n; i++) {if (selected[i]) {System.out.println("选择的课程教师ID: " + values[i]);}}foundOptimal = true; // 标记已找到最优解return true;}return false;}// 不选择当前课程selected[index] = false;printSelectedCourses(index + 1, weights, values, currentCapacity, n, selected, maxValue);// 尝试选择当前课程if (currentCapacity >= weights[index]) {selected[index] = true;printSelectedCourses(index + 1, weights, values, currentCapacity - weights[index], n, selected, maxValue);}return false;}

3.使用动态规划算法模拟课程安排优化

1. `optimizeCourseScheduling` 方法:

    作用:优化课程安排,使用递归模拟动态规划过程。

    参数列表:

      `Scanner scanner`:用于接收用户输入的扫描器。

      `CourseService courseService`:用于获取课程数据的服务类。

2. `knapsack` 方法:

    作用:模拟动态规划解决背包问题,计算最大化的课程安排价值。

    参数列表:

      `int index`:当前处理的课程索引。

      `int[] weights`:每个课程占用的教室数量。

      `int[] values`:每个课程的价值(教师ID)。

      `int capacity`:当前剩余的教室容量。

      `int n`:课程总数。

3. `printSelectedCourses` 方法:

    作用:递归回溯函数,意图是打印出被选中的课程和教师ID。

    参数列表:

      `int index`:当前处理的课程索引。

      `int[] weights`:每个课程占用的教室数量。

      `int[] values`:每个课程的价值(教师ID)。

      `int currentCapacity`:当前剩余的教室容量。

      `int n`:课程总数。

      `boolean[] selected`:标记数组,表示每个课程是否被选择。

      `int maxValue`:最大化的课程安排价值。

 详细描述

1. `optimizeCourseScheduling` 方法:

    该方法首先接收用户输入的教室容量,然后获取所有课程数据。

    为每门课程分配教师ID和教室资源,并初始化权重和价值数组。

    调用 `knapsack` 方法计算最大化的课程安排价值。

    初始化标记数组 `selected`,并调用 `printSelectedCourses` 方法打印出被选中的课程和教师ID。

    如果未找到符合条件的课程安排,则输出提示信息。

2. `knapsack` 方法:

    该方法是用于模拟动态规划解决背包问题。

    基本情况:如果没有课程可选或背包容量为0,则返回0。

    如果当前课程的重量大于背包容量,则不能选择该课程。

    递归选择:选择包含当前课程或不包含当前课程的最大价值。

3. `printSelectedCourses` 方法:

    该方法是递归回溯函数,用于打印出被选中的课程和教师ID。

    如果已经找到最优解,直接返回。

    递归终止条件:如果处理完所有课程,计算当前选择的课程价值,如果满足条件则打印选择的课程并标记已找到最优解。

    不选择当前课程,继续递归处理下一个课程。

    尝试选择当前课程,如果当前容量足够,继续递归处理下一个课程。

总结

这段代码的核心是一个简化的课程安排优化问题,模拟动态规划算法,以解决类似于背包问题的资源分配问题。程序的目标是在有限的教室资源下最大化课程的总价值,这里使用教师ID作为价值的代表。

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

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

相关文章

干货 | 2024大模型场景下智算平台的设计与优化实践(免费下载)

诚挚邀请您微信扫描以下二维码加入方案驿站知识星球&#xff0c;获取上万份PPT/WORD解决方案&#xff01;&#xff01;&#xff01;感谢支持&#xff01;&#xff01;&#xff01;

android pdf框架-11,查看图片

前10篇文章,9章关于pdf的,pdf解析后,里面也是有各种图片,于是利用pdf的view来展示图片,似乎也是个不错的想法. android手机中的图片查看功能,有的可以展示,有的不能.比如华为,荣耀对大体积的png是可以显示的,小米是不显示,只有缩略图. 一张png50m大,比如清明上河图,原图是tif…

【C++】string的底层原理及实现

文章目录 string类的存储结构默认成员函数构造函数析构函数拷贝构造函数赋值重载 容量操作size()capacity()reserve()resize()clear() 遍历与访问operator[ ]迭代器范围与for 增删查改push_back()pop_back()append()operatorinsert()erase()c_str()find()substr() 非成员函数op…

c#的List<T>的SelectMany 和Select

在C#中&#xff0c;List<T>&#xff08;以及任何实现了IEnumerable<T>的集合&#xff09;的Select和SelectMany扩展方法都是LINQ&#xff08;Language Integrated Query&#xff09;的一部分&#xff0c;用于对集合中的元素进行查询和转换。 尽管它们的作用有些相…

Virtualbox和ubuntu之间的关系

1、什么是ubuntu Ubuntu 是一个类似于 Windows 的操作系统&#xff0c;但它是基于 Linux 内核开发的开源操作系统 2、什么是Virtualbox VirtualBox 是一款虚拟机软件&#xff0c;使我们可以物理机上创建和运行虚拟机 也就是说,VirtualBox 提供了一个可以安装和运行其他操作系…

力扣考研经典题 反转链表

核心思想 头插法&#xff1a; 不断的将cur指针所指向的节点放到头节点之前&#xff0c;然后头节点指向cur节点&#xff0c;因为最后返回的是head.next 。 解题思路 1.如果头节点是空的&#xff0c;或者是只有一个节点&#xff0c;只需要返回head节点即可。 if (head null …

算法训练营day70

题目1&#xff1a;108. 冗余连接 (kamacoder.com) #include<iostream> #include<vector>using namespace std;int n; vector<int> father(10001, 0);void init() {for(int i 1;i < n;i) father[i] i; }int find(int u) {return u father[u] ? u : fa…

Echarts中的热力图和漏斗图(在Vue中使用热力图和漏斗图)

热力图 (Heatmap) Echarts的热力图用于展示两个维度数据矩阵中的值分布情况。它通过在平面上划分成多个矩形区域&#xff0c;并用不同的颜色填充这些区域来表示数据的大小或强度。颜色渐变从浅到深通常映射着数值从小到大&#xff0c;从而直观展示数据的集中程度和分布模式。热…

Mojolicious测试驱动开发:单元与集成测试的艺术

标题&#xff1a;Mojolicious测试驱动开发&#xff1a;单元与集成测试的艺术 Mojolicious是一个现代化的Perl Web开发框架&#xff0c;它不仅提供了强大的Web应用开发能力&#xff0c;还内置了丰富的测试工具来支持单元测试和集成测试。本文将深入探讨如何在Mojolicious中进行…

人工智能期末复习简答题

简答: 子句集的化简(1).消去连接词”—>”和”<—>” (2)减少否定符号的辖域 (3)对变元标准化 (4)化为前束范式 (5)消去存在量词 (6)化为Skolem标准形 (7)消去全称量词 (8)消去合取词 (9)更换变元名称 2.在状态空间搜索中,Open表与Close…

半同步主从复制

半同步主从复制的概念 半同步主从复制&#xff08;Semisynchronous Replication, SBR&#xff09;是MySQL数据库中的一种数据复制方式&#xff0c;它在异步复制的基础上增加了一定程度的同步性&#xff0c;旨在提高数据安全性&#xff0c;减少数据丢失的风险。 半同步主从复制…

LeetCode 3101.交替子数组计数:等差数列求和(较详题解)

【LetMeFly】3101.交替子数组计数&#xff1a;等差数列求和&#xff08;较详题解&#xff09; 力扣题目链接&#xff1a;https://leetcode.cn/problems/count-alternating-subarrays/ 给你一个二进制数组 nums 。 如果一个子数组中 不存在 两个 相邻 元素的值 相同 的情况&a…

阶段三:项目开发---大数据开发运行环境搭建:任务8:安装配置Redis

任务描述 知识点&#xff1a;安装配置Redis 重 点&#xff1a; 安装配置Redis 难 点&#xff1a;无 内 容&#xff1a; Redis&#xff08;Remote Dictionary Server )&#xff0c;即远程字典服务&#xff0c;是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可…

【C++:运算符重载】

运算符重载 特点&#xff1a; 函数名由operator运算符组成 注&#xff1a; 不能通过其他符号创建新的操作符&#xff0c;只能使用C/C语法存在的操作符重载操作符必须有一个类类型参数&#xff0c;原因&#xff1a;不能重载操作符改变内置类型的行为当类成员操作符重载时&#…

web自动化(五)上传文件

我们需要准备一个上传文件的html&#xff0c;创建a.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>文件上传示例</title> </head> <body><form action"/upload"…

电路基础知识汇总

1.0 串连&#xff0c;并联&#xff0c;混连 串联的定义 电路串联是一种电路元件的连接方式&#xff0c;其中各个元件沿着单一路径互相连接&#xff0c;形成一个连续的链。在串联电路中&#xff0c;每个节点最多只连接两个元件&#xff0c;这意味着电流只有一条路径可以通过整个…

Apache Seata Mac下的Seata Demo环境搭建

本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 Mac下的Seata Demo环境搭建&#xff08;AT模式&#xff09; 前言 最近因为工作需要&#xf…

Git教程

文章目录 Git分布式版本控制工具版本控制器的方式常用命令远程仓库Tip Git分布式版本控制工具 ​ Git是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理。 ​ Git是分布式的&#xff0c;Git不需要有中心服务器&#xff0c;我们每…

【感谢告知】本账号内容调整,聚焦于Google账号和产品的使用经验和问题案例分析

亲爱的各位朋友&#xff1a; 感谢您对本账号的关注和支持&#xff01; 基于对朋友们需求的分析和个人兴趣的转变&#xff0c;该账号从今天将对内容做一些调整&#xff0c;有原来的内容改为Google&#xff08;谷歌&#xff09;账号和产品的使用经验&#xff0c;以及相关问题的…

24西安电子科技大学经济与管理学院—考研录取情况

24西安电子科技大学—经理与管理学院—考研录取统计 01、经理与管理学院各个方向 02、24经济与管理近三年复试分数线对比 1、经管院24年院线相对于23年院线普遍下降2-15分&#xff0c;个别专业上涨4-10分。 2、经管院应用经济学2024年院线350分&#xff1b;管理科学与工程院线…