在给定开始/结束时间数组的情况下查找总空闲时间的算法

Posted

技术标签:

【中文标题】在给定开始/结束时间数组的情况下查找总空闲时间的算法【英文标题】:Algorithm for finding total idle time given array of start/end times 【发布时间】:2009-04-14 17:09:11 【问题描述】:

假设给你一个开始和结束时间。

此外,您还会获得一组作业,并按开始和结束时间进行描述。这些作业可能重叠(即,可以同时运行多个作业)。我需要找到一种方法来确定有多少时间闲置而没有运行任何工作。

当然,如果任何时候只能运行一个作业,我可以减去每个作业的运行时间,但重叠部分让我很难过。

【问题讨论】:

【参考方案1】:

对时间进行排序,然后按顺序遍历它们。 如果某个时间是开始时间,则将正在运行的任务数加 1。 如果是停止时间,则减 1。 跟踪任务数为 0 时还有多少时间。

【讨论】:

【参考方案2】:

将所有开始和结束时间放入一个数组中,将它们标记为开始时间或结束时间。按时间对数组进行排序。现在遍历排序列表,记录有多少作业正在运行:

在读取开始时间时增加计数器 在读取结束时间时递减计数器

每当您从零递增到一时,将 (current_time - previous_time) 添加到总空闲时间。如有必要,请记住还要对开始和结束进行特殊处理。

【讨论】:

【参考方案3】:

这里有一个稍微不同的方法。第一部分用于说明目的。

创建一个整数数组,表示所有作业的完整时间线。这可以是几小时、几分钟或任何您需要的时间。我会假设几个小时。找到最早开始时间和最晚结束时间来设置数组的大小。将所有元素初始化为零。

循环遍历每个作业,为作业运行的每一小时增加时间轴中的计数器。因此,如果作业从下午 3 点运行到下午 5 点,则为两个小时,因此您需要增加 3 小时和 4 小时的时间间隔,以指示作业在这些时间段内运行。

循环遍历时间线,记录您遇到的零的数量。这些是没有作业运行的时间段。

现在,如果您理解这一点,那么摆脱数组就很容易了。无需创建(可能很大)数组,只需跟踪整个时间线的开始和结束时间。对于该范围内的每个小时,循环遍历所有作业,并查看在此期间有多少作业在运行。任何为零的都是空闲时间。

【讨论】:

这是我想采取的方法,因为它避免了工作在午夜结束的问题。【参考方案4】:
Sort the jobs based on their end times.

Jobs<startTime,EndTime>[] = contains the Sorted list.

Take first Job in the list
Jobs[0]

intialize:
    EndTime = Job[0].EndTime
    StartTime = Job[0].StartTime
     idleTime =0;

For i = 1 till Jobs.size

    if ( Jobs[i].EndTime >= StartTime )
    
        //Do nothing, its overlapping
    
    else
     //Previoys Job time doesnot overlap, so get the idle time.
        idleTime += (StartTime -Jobs[i].EndTime);
    

     StartTime = Jobs[i].StartTime;
     EndTime = Jobs[i].EndTime;

【讨论】:

【参考方案5】:

当一个或多个作业正在运行时,您有大量的忙碌时间。 空闲时间是繁忙块之间时间跨度的总和。 伪代码:

idle_time = 0
sort jobs by start time
foreach job in jobs

  if (job.start > current_chunk.end)
  
    idle_time += job.start - current_chunk.end
  
  if (job.end > current_chunk.end)
  
    current_chunk.end = job.end
  

注意:为简单起见,我省略了处理第一个元素的代码。

【讨论】:

【参考方案6】:

我们有 2 个作业的开始时间和结束时间数组。作业可以重叠,如以下两个示例数组。

startTime = [2.1, 5.0, 8.3, 14.1 ,16.5, 24.2 ,28.1, 40.6 ,42.3 , 45.4 ]
endTime =  [4.0 ,10.0 ,9.3 ,18.1 ,26.5 ,25.3, 36.6 ,60.6, 44.3 ,55.4]

我们必须计算系统的空闲时间。在这种情况下,计算是: Total idle time = 2.1 + (5.0-4.0) + (14.1-10.0) + (28.1-26.5) + (40.6-36.6) = 12.8 units

所以,解决办法是:

startTime = [2.1 , 5.0  , 8.3 , 14.1 , 16.5 , 24.2 , 28.1 , 40.6 , 42.3 ]
endTime =   [4.0 , 10.0 , 9.3 , 18.1 , 26.5 , 25.3 , 36.6 , 60.6 , 44.3 ]

if len(startTime)>0:
    idleTime = startTime[0];
    eT =  endTime[0];
    i = 1 
    while i < len(startTime):
        if startTime[i]>eT:
            idleTime += (startTime[i] -eT)
            eT = endTime[i]
        else:
            if endTime[i]>eT:
                eT = endTime[i]
        i+=1
    print("Idle Time is : " , idleTime )    
else:
    print ("Idle Time is : " , 0 )

【讨论】:

以上是关于在给定开始/结束时间数组的情况下查找总空闲时间的算法的主要内容,如果未能解决你的问题,请参考以下文章

在给定日期时间连续性的情况下,Pandas 输出日期、开始和结束时间以及事件状态

如何使用开始和结束日期时间在司机的行程中查找重叠记录

Mysql Select Query 以查找在两个给定日期之间也部分空闲的项目

在给定每个数量数量的成本和我们的总资金的情况下最大化数量数量

[算法][原创]最简单的二分查找左右边界思路

在排序数组中查找元素