最佳调度问题

LeetCode参考:https://leetcode.cn/problems/find-minimum-time-to-finish-all-jobs/description/

算法设计思路

回溯法:深度优先搜索 + 剪枝。

将问题抽象为一棵深度为 n n n k k k 叉树。树中结点的关键字即为完成任务所需的时间 t i t_i ti

首先,我们选择个分支一直往下走,以DFS来搜索整个解空间。每次搜索到达叶结点都判断是否是最优路径。若是,更新最优时间bestTime和与之对应的最优调度bestSchedule。一开始我们需要完整的走完一条路径,后面再进行遍历的时候只需要与现有的数据进行比较,当我们发现当前机器的运行时间已经超过当前的最优解时便停止遍历,即进行剪枝操作。以tasks=[3, 2, 3],k=3为例,算法得部分运行步骤如下所示:

源码

class Solution {
private int bestTime = Integer.MAX_VALUE;
public int minimumTimeRequired(int[] jobs, int k) {
int[] machineTime = new int[k];
backtrack(0, 0, jobs.length, k, jobs, machineTime);
return bestTime;
}
public void backtrack(int taskIndex, int curTime, int n, int k, int[] tasks, int[] machineTime) {
if (taskIndex == n) { // 遍历到叶结点
if (curTime < bestTime) { // 如果当前花费的时间小于之前的最优时间
bestTime = curTime; // 更新最优时间
}
return;
}
for (int machine = 0; machine < k; machine++) {
if (machineTime[machine] + tasks[taskIndex] >= bestTime) { // 剪枝,加上完成当前任务的时间大于最优时间,不需要进入递归
continue;
}
if (machine > 0 && machineTime[machine] == machineTime[machine-1]) { // 剪枝,如果和之前的相同,不需要进入递归
continue;
}
machineTime[machine] += tasks[taskIndex]; // 加上花费的时间
if (Math.max(curTime, machineTime[machine]) < bestTime) {
backtrack(taskIndex + 1, Math.max(curTime, machineTime[machine]), n, k, tasks, machineTime);
}
machineTime[machine] -= tasks[taskIndex]; // 回溯
}
}
}
posted @   gengduc  阅读(123)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示