📌  相关文章
📜  完成所有任务所需的最短时间,允许更改订单(1)

📅  最后修改于: 2023-12-03 15:09:26.189000             🧑  作者: Mango

完成所有任务所需的最短时间,允许更改订单

问题描述

有M个任务需要完成,每个任务需要x1, x2, ... , xm的时间才能完成,每个任务都需要一个员工来完成。现在有N个员工可供选择,并且每个员工都有一个基础工作效率yi,也就是说,如果选择该员工完成任务i,那么完成该任务需要的实际时间是xi/yi。由于客户需求的变化,可能需要更改任务安排的顺序,请你在保证所有任务都能按时完成的前提下,计算完成所有任务所需的最短时间。

解题思路

首先,让我们考虑如何计算某个员工在完成某个任务时需要花费的时间。设该员工基础工作效率为yi,任务i需要完成的时间为xi,则完成该任务的实际时间为 xi/yi。

接着,我们想到可以将每个员工的基础工作效率排序,并将他们从高到低依次与任务配对,使得总用时最少。

最后,若需要更改某些任务的顺序,我们可以通过修改完成时间最长的任务的顺序来达到最短用时的目的。即将完成时间最长的任务放到最后面即可。

代码实现
def minTimeToFinishTasks(n, m, workEfficiency, taskDuration, changeList):
    # 计算完成某个任务所需时间
    taskTime = [0] * m
    for i in range(m):
        taskTime[i] = [(taskDuration[i] / workEfficiency[j], j) for j in range(n)]
    
    # 将员工按基础工作效率排序
    workEfficiency = sorted(workEfficiency, reverse=True)
    taskTime.sort(key=lambda x: x[0][0], reverse=False)
    
    # 配对
    totalTime = 0
    for i in range(m):
        t = taskTime[i]
        for j in range(n):
            if t[j][1] not in changeList:
                totalTime += t[j][0]  # 该员工未被更改,直接完成任务
                workEfficiency.remove(workEfficiency[j])
                taskTime[i].remove(t[j])
                n -= 1
                break
        else:
            totalTime += t[-1][0]  # 所有员工都被更改,选择工作效率最低的员工完成该任务
    
    return totalTime
示例

假设有3个员工,4个任务,他们完成任务所需的时间分别为:

工作效率:   9  10  7
任务完成时间:7  10  6  4

则每个员工完成任务所需的实际时间如下:

(9,2)(10,1)(7,0)  # 第i个元素表示:员工i完成任务需要花费的实际时间和他的编号
(7/7,2)(10/10,1)(6/7,0)(4/9,2)

(9,0)(10,1)(7,2)
(4/7,2)(6/10,1)(7/7,0)(10/9,2)

按工作效率排序后,每个员工与任务配对的结果如下:

(4/7,2)(7/7,0)(6/10,1)(10/9,2)

由此,可得所有任务完成所需的最短时间为:

4/7 + 7/7 + 6/10 + 10/9 = 2.75
总结

以上就是完成所有任务所需的最短时间,允许更改订单的算法实现方法。通过将任务完成所需时间和员工基础工作效率进行匹配,并且按照工作效率从高到低进行排序,可以使总用时最短。如果需要修改任务的顺序,则只需要将完成时间最长的任务放到最后即可。