【华为OD机试】任务调度

文章描述了一个CPU任务调度问题,使用可抢占优先权调度算法。程序需处理任务ID、优先级、执行时间和到达时间,当有更高优先级任务到达时,CPU会暂停当前任务。解决方案涉及使用TreeMap存储按优先级排序的任务,并结合链表处理相同优先级的任务。代码示例展示了如何执行任务并返回执行结果。
摘要由CSDN通过智能技术生成

任务调度

题目描述

现有一个CPU和一些任务需要处理,已提前获知每个任务的任务ID、优先级、所需执行时间和到达时间。

CPU同时只能运行一个任务,请编写一个任务调度程序,采用“可抢占优先权调度”调度算法进行任务调度,规则如下:

  • 如果一个任务到来时,CPU是空闲的,则CPU可以运行该任务直到任务执行完毕。
  • 但是如果运行中有一个更高优先级的任务到来,则CPU必须暂停当前任务去运行这个优先级更高的任务;
  • 如果一个任务到来时,CPU正在运行一个比他优先级更高的任务时,信道大的任务必须等待;
  • 当CPU空闲时,如果还有任务在等待,CPU会从这些任务中选择一个优先级更高的任务执行,相同优先级的任务选择到达时间最早的任务。

输入描述

输入有若干行,每一行有四个数字(均小于 10^8),分别为任务ID、任务优先级、执行时间和到达时间。

每个任务的任务ID不同,优先级数字越大优先级越高,并且相同优先级的任务不会同时到达。

输入的任务已按照到达时间从小到大排序,并且保证在任何时间,处于等待的任务不超过 10000 个。

输出描述

按照任务执行结束的顺序

测试用例

输入

1 3 5 2
2 1 3 6
3 2 5 11
4 2 6 12
5 3 3 15

输出

[0]:任务ID;[1]:任务完成时间

1 7
2 10
5 18
3 19
4 25

解题思路

题目解析

  1. CPU空闲时可执行任务;
  2. 优先级高的任务到来会暂停当前任务,在下一个任务到来前无法确认当前任务是否被暂停;
  3. 当前任务与上一任务到达时间之差可以明确为CPU空闲时间,该段时间可执行当前任务之前的任务;
  4. 需要有个结构可以存储优先级与任务的关系作为待执行任务池,同时需要根据优先级进行排序,此处可以选用TreeMap结构;
  5. 相同优先级任务按到达时间执行,可选择链表结构

代码示例

/**
  * 执行任务
  * @param tasks 待执行任务(按任务到达时间由小到大)
  * @return 任务执行结果
  */
public List<String> startTask(int[][] tasks) {
    // 当前时间
    int endTime = 0;
    // 执行结果
    List<String> result = new ArrayList<>();
    // 任务池,key:任务优先级;value:任务链表
    TreeMap<Integer, LinkedList<int[]>> pool = new TreeMap<>();

    for(int[] task : tasks) {
        // 任务到达之前与上一次执行间隙时间,处理该段时间可执行任务
        startPoolTask(endTime, task[3] - endTime, pool, result);
        // 将当前任务放至任务池
        pool.putIfAbsent(task[1], new LinkedList<>());
        pool.get(task[1]).add(task);
        // 更新时间为结束时间
        endTime = task[3];
    }

    // 任务添加完毕,顺序执行任务池中任务
    Map.Entry<Integer, LinkedList<int[]>> entry;
    while(!pool.isEmpty()) {
        entry = pool.pollLastEntry();
        for (int[] task : entry.getValue()) {
            endTime += task[2];
            result.add(task[0] + " " + endTime);
        }
    }

    return result;
}

/**
 * 执行等待队列中CPU任务
 * @param curTime 当前时间
 * @param time 可执行CPU任务时间
 * @param tasks 待执行CPU任务
 * @param result 执行结果
 */
private void startPoolTask(int curTime, int time, TreeMap<Integer, LinkedList<int[]>> tasks, List<String> result) {
    // 不存在可执行时间,直接跳过
    if(time <= 0) {
        return;
    }
    // 无等待任务
    if(tasks.isEmpty()) {
        return;
    }
    // 获取优先级最高的任务列表
    Map.Entry<Integer, LinkedList<int[]>> entry = tasks.lastEntry();
    LinkedList<int[]> list = entry.getValue();
    // 取出列表中最先到达的任务
    int[] task = list.getFirst();
    // 任务所需时间大于可执行时间,更新任务所需时间
    if(time < task[2]) {
        task[2] -= time;
        return;
    }
    // 任务执行完成后从队列中移除,并添加执行结果
    list.pop();
    result.add(task[0] + " " + (curTime + task[2]));
    // 若移除后任务列表为空,移除该优先级任务列表
    if(list.isEmpty()) {
        tasks.remove(entry.getKey());
    }
    // 执行下一次CPU空闲任务
    startPoolTask(curTime + task[2], time - task[2], tasks, result);
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值