1.贪心算法介绍
1.算法思路
贪心算法的基本思路是从问题的某一个初始解出发一步一步地进行,根据某个优化测度,每一 步都要确保能获得局部最优解。每一步只考虑一 个数据,其选取应该满足局部优化的条件。若下 一个数据和部分最优解连在一起不再是可行解时, 就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加算法停止。
贪心算法一般按如下步骤进行:
①建立数学模型来描述问题 。
②把求解的问题分成若干个子问题 。
③对每个子问题求解,得到子问题的局部最优解 。
④把子问题的解局部最优解合成原来解问题的一个解 。
贪心算法是一种对某些求最优解问题的更简单、更迅速的设计技术。贪心算法的特点是一步一步地进行,常以当前情况为基础根据某个优化测度作最优选择,而不考虑各种可能的整体情况,省去了为找最优解要穷尽所有可能而必须耗费的大量时间。贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择,就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解。虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪心算法不要回溯 [2]。
2.代码介绍
java
// 定义一个静态方法,用于分配教学任务,需要TeacherService, TitleService, PositionService三个服务层对象
private static void assignTeachingTasks(TeacherService teacherService, TitleService titleService, PositionService positionService) {
// 从TeacherService获取所有教师的列表
List<Teacher> teachers = teacherService.getAllTeachers();
// 如果教师列表为空,打印消息并返回
if (teachers == null || teachers.isEmpty()) {
System.out.println("没有教师信息!");
return;
}
// 创建一个优先队列,用于根据教师的职称和职务优先级排序
PriorityQueue<Teacher> priorityQueue = new PriorityQueue<>((t1, t2) -> {
// 通过TitleService获取教师1的职称
Title title1 = titleService.getTitleById(t1.getTitleId());
// 通过TitleService获取教师2的职称
Title title2 = titleService.getTitleById(t2.getTitleId());
// 通过PositionService获取教师1的职务
Position position1 = positionService.getPositionById(t1.getPositionId());
// 通过PositionService获取教师2的职务
Position position2 = positionService.getPositionById(t2.getPositionId());
// 获取教师1的职称优先级,如果职称对象为null,则默认优先级为0
int titlePriority1 = title1 != null ? title1.getPriority() : 0;
// 获取教师2的职称优先级,如果职称对象为null,则默认优先级为0
int titlePriority2 = title2 != null ? title2.getPriority() : 0;
// 获取教师1的职务优先级,如果职务对象为null,则默认优先级为0
int positionPriority1 = position1 != null ? position1.getPriority() : 0;
// 获取教师2的职务优先级,如果职务对象为null,则默认优先级为0
int positionPriority2 = position2 != null ? position2.getPriority() : 0;
// 比较两个教师的综合优先级,返回一个整数,表示t2相对于t1的优先级
// 如果返回值小于0,t1会被认为优先级更高,会被排在前面
// 如果返回值大于0,t2会被认为优先级更高,会被排在前面
// 如果返回值等于0,t1和t2的优先级相同
return (titlePriority2 + positionPriority2) - (titlePriority1 + positionPriority1);
});
// 将所有教师添加到优先队列中
priorityQueue.addAll(teachers);
// 初始化任务计数器
int taskCount = 1;
// 当优先队列不为空时,循环分配任务
while (!priorityQueue.isEmpty()) {
// 从优先队列中取出优先级最高的教师
Teacher teacher = priorityQueue.poll();
// 打印分配任务的消息
System.out.println("根据任务重要情况依次分配教学任务 " + taskCount + " 给教师 " + teacher.getName());
// 任务计数器递增
taskCount++;
}
}
3.使用贪心算法来分配教学任务
assignTeachingTasks的静态方法,其目的是使用贪心算法的思想来根据教师的职称和职务的优先级分配教学任务
- 方法参数:
接收三个服务层对象:`TeacherService`、`TitleService` 和 `PositionService`,分别用于获取和管理教师、职称和职务信息。
- 获取教师列表:
通过 `teacherService.getAllTeachers()` 获取所有教师的列表。
- 检查教师列表是否为空:
如果教师列表为空,打印提示信息并返回。
- 创建优先队列:
使用 `PriorityQueue` 创建一个优先队列,根据教师的职称和职务的优先级进行排序。这是贪心算法的应用,因为它总是选择当前优先级最高的教师进行任务分配。
- 自定义比较器逻辑:
比较器通过服务层对象获取每个教师的职称和职务,并获取它们的优先级。如果职称或职务对象为 `null`,则默认优先级为 `0`。然后计算每个教师的综合优先级,并进行比较。
- 添加教师到优先队列:
将所有教师添加到优先队列中。
- 初始化任务计数器:
初始化一个计数器 `taskCount`,用于跟踪分配给教师的任务编号。
- 分配任务循环:
当优先队列不为空时,循环执行以下操作:
使用 `poll` 方法从队列中取出优先级最高的教师。
打印一条消息,显示分配给该教师的任务编号。
递增任务计数器。
- 贪心算法的应用:
贪心算法在这里的应用体现在每次从优先队列中取出教师时,都是取出当前队列中优先级最高的教师。这符合贪心算法的局部最优选择原则,即在每一步选择中都采取当前状态下最好或最优的选择。
- 简单高效:
贪心算法通常简单且效率较高,因为它们只需要考虑当前的最优选择,而不需要考虑所有可能的全局情况。在这个方法中,通过优先队列实现的贪心选择快速定位到最高优先级的教师,从而快速进行任务分配。