Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Algorithm for finding total idle time given array of start/end times

Tags:

algorithm

Say you're given a start and end time.

Also you're given an array of jobs, described by their start and end times. These jobs may overlap (ie, there can be multiple jobs running at once). I need to find a way to determine how much time was spent idle and not running any job.

Of course, if only one job can be running at any time, I could just subtract out the running times of each job, but the overlap part has me stumped.

like image 231
accelerate Avatar asked Apr 14 '09 17:04

accelerate


4 Answers

Sort the times, and then run through them in order.
If a time is a start time, add 1 to the number of tasks running.
If it is a stop time, subtract 1.
Keep track of how much time there is when the number of tasks is 0.

like image 192
Mike Dunlavey Avatar answered Nov 19 '22 19:11

Mike Dunlavey


Put all the start and end times into a single array, tagging them as either start or end times. Sort the array by time. Now iterate through the sorted list, keeping a count of how many jobs are running by:

  • incrementing the counter when reading a start time
  • decrementing the counter when reading an end time

Whenever you increment from zero to one, add (current_time - previous_time) to the total idle time. Remember to also special case the start and end if necessary.

like image 40
moinudin Avatar answered Nov 19 '22 20:11

moinudin


Here's a slightly different approach. The first part is for illustrative purpose.

Create an array of ints representing the full timeline of all jobs. This can be in hours, minutes, or whatever you need. I'll assume hours. Find the earliest start time and latest end time to set the size of the array. Initialize all elements to zero.

Loop through each job, incrementing the counter in the timeline for each hour the job is running. So if a job runs from 3pm to 5pm, that's two hours, so you'd increment the 3-hour and the 4-hour slot to indicate that a job was running during those hours.

Loop through the timeline, keeping count of how many zeroes you encounter. Those are the time slots where no job was running.

Now, if you understand that, it's pretty easy to get rid of the array. Instead of creating a (potintially large) array, just keep track of the begin and end time of the entire time line. For each hour in that range loop through all your jobs and see how many are running during that time. Any that are zero are idle times.

like image 3
Bill the Lizard Avatar answered Nov 19 '22 20:11

Bill the Lizard


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;
}
like image 1
aJ. Avatar answered Nov 19 '22 18:11

aJ.