1.动态规划算法介绍
1.算法思路
动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。具体的动态规划算法多种多样,但它们具有相同的填表格式。
2.代码介绍
// 优化课程安排,使用递归模拟动态规划过程
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);
// 打印选择的课程和对应的教师ID
// 这里应该使用回溯算法来打印结果,但当前实现不正确
printSelectedCourses(0, weights, values, capacity, n);
}
// 递归函数模拟动态规划解决背包问题
// 递归的深度为课程数量n,每层递归的复杂度与教室容量有关
private static int knapsack(int index, int[] weights, int[] values, int capacity, int n) {
// 基本情况:没有课程可选或背包容量为0
if (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) // 选择当前课程
);
}
// 递归回溯函数,意图是打印出被选中的课程和教师ID
private static void printSelectedCourses(int index, int[] weights, int[] values, int capacity, int n) {
if (index == n) {
return;
}
// 如果当前容量不足以包含当前课程,则只能不选择当前课程
if (capacity < weights[index]) {
printSelectedCourses(index + 1, weights, values, capacity, n);
return;
}
// 尝试不选择当前课程
printSelectedCourses(index + 1, weights, values, capacity, n);
// 尝试选择当前课程
if (knapsack(index + 1, weights, values, capacity - weights[index], n) < knapsack(index + 1, weights, values, capacity, n)) {
System.out.println("选择的课程教师ID: " + values[index]);
printSelectedCourses(index + 1, weights, values, capacity - weights[index], n);
}
}
3.使用动态规划算法模拟课程安排优化
optimizeCourseScheduling
方法
- 作用:优化课程安排的主要方法。
- 读取用户输入的可用教室数量。
- 获取所有课程的详细信息,包括每门课程的教师ID。
- 为每门课程分配一个固定的教室数量(这里简化为每个课程占用一个教室)。
- 调用
knapsack
方法计算在给定教室数量下的最大课程安排价值。 - 打印出最大价值,并尝试调用
printSelectedCourses
方法打印被选中的课程和教师ID。
knapsack
方法
- 作用:实现的背包问题算法。
- 模拟动态规划过程,尝试不同的课程组合来找到最大价值。
- 基本情况:如果没有课程可选或背包容量为0,返回0。
- 递归决策:对于每个课程,决策是否将其包含在内,以获得最大价值。
- 返回在当前容量下,考虑前
index
个课程时的最大价值。
printSelectedCourses
方法
- 作用:用于打印出被选中的课程和对应的教师ID。
总结
这段代码的核心是一个简化的课程安排优化问题,模拟动态规划算法,以解决类似于背包问题的资源分配问题。程序的目标是在有限的教室资源下最大化课程的总价值,这里使用教师ID作为价值的代表。
标签:index,capacity,管理系统,int,values,为例,课程,weights,排班 From: https://blog.csdn.net/weixin_64922330/article/details/140244001