tags:

views:

110

answers:

4

Baselines - table:

date / time of call, duration of call

How to calculate "Busy hour"?

http://en.wikipedia.org/wiki/Busy_hour - In a communications system, the sliding 60-minute period during which occurs the maximum total traffic load in a given 24-hour period.

+4  A: 

For an extended period (as many days as you can be bothered to compute for) calculate the number of calls active at each minute of the day -- there are 1440 of them. Then for each minute of the day calculate the moving 60-minute sum of active calls, the minute for which this sum is maximised is the start of the busy hour (provided that you've calculated forward moving averages). Don't forget to wrap around at midnight.

This seems so simple that I suspect I've misunderstood your question.

High Performance Mark
Doesnt that assume minute granularity? I could envisage some tricky edge cases whereby a call volume that varied second by second could get lost.
Visage
@Visage: so could I, so assume second granularity, or millisecond granularity if that's what's appropriate for your case. Either way it's only going to take a couple of minutes to calculate.
High Performance Mark
Given that going from minute accuracy to millisecond accuracy would entail an increase in magnitude of 10^4 I dont think you can write off the difference so easily.
Visage
@Visage: of course I can, I have access to clusters with >10^4 processor cores ! But it's really for OP to determine what granularity to calculate for.
High Performance Mark
A: 

sum the first one hour and note the sum. then add all traffic of the next minute and remove the traffic of the first minute. If this sum is greater then the first one - note it and go on.

sth like the crude code here

Minute busyHourStart = 0;
Minute currentStart = 0;
int busyHourSum = 0;
int currentSum = 0;


while( minutesLeft){

   currentSum = sumTrafficForMinutes(currentStart, currentStart + 60);

   if(busyHourSum < currentSum){
      busyHourSum = currentSum
      busyHourStart = currentStart;
   }

    ++currentStart;
}
kostja
A: 

This can be done in linear time, by using two pointers (Left and Right) traversing the sorted list of events. Actually, the traversing is done on a sorted list of call events, containing both call start events and call end events.

The left pointer starts from the leftmost start event. The right pointer moves to the latest event not later than (left ptr time + 1hr). We also maintain a sum variable that calculates the total of all call durations in the interval.

At each iteration we move the left pointer to the next event (updating the sum accordingly), and then we progress with the right pointer (updating the sum, again) until its end position (little less than 1 hr later).

The maximum value of sum is obtained at the busy hour window.

I didn't give details on how to update the sum variable when moving the pointers, but I believe it should not be complicated to do it in constant time.

The advantage of this algorithm is that it does not have the granularity problem, and that it is linear in the number of events.

--EDIT--

Actually this is an O(N*Log N) algorithm, since the input table does not provide the sorting of events that I assumed. We need to generate the sorted lists of events first

Eyal Schneider
A: 

Have a sort of 1D heat map.

Layer the calls onto the map that shows time, then find the 'hottest' hour.

Tom Gullen
Nice idea, but this still requires defining some granularity of time, and consuming array space accordingly. My solution (though a little complicated and not worthwhile for small inputs) avoids this and offers a near linear solution in the number of events.
Eyal Schneider