给定一个时间范围列表,我需要找到最大重叠次数。
以下是显示10分钟通话间隔的数据集 我试图在其中找到最大活动行数 间隔。即。从下面的示例中,同时处于活动状态的最大呼叫数是多少:
CallStart CallEnd
2:22:22 PM 2:22:33 PM
2:22:35 PM 2:22:42 PM
2:22:36 PM 2:22:43 PM
2:22:46 PM 2:22:54 PM
2:22:49 PM 2:27:21 PM
2:22:57 PM 2:23:03 PM
2:23:29 PM 2:23:40 PM
2:24:08 PM 2:24:14 PM
2:27:37 PM 2:39:14 PM
2:27:47 PM 2:27:55 PM
2:29:04 PM 2:29:26 PM
2:29:31 PM 2:29:43 PM
2:29:45 PM 2:30:10 PM
如果有人知道一个算法,或者能指出我正确的方向,我 不胜感激。
TIA,
Steve F
答案 0 :(得分:52)
以下必须工作:
numberOfCalls
设为0(计数变量)运行您的时间值并:
复杂性:O(n log(n))用于排序,O(n)用于遍历所有记录
答案 1 :(得分:1)
天真的方法怎么样:
我猜你也可以把它塑造成一个图形并且摆弄一下,但是此刻打败了我。
答案 2 :(得分:1)
在我看来,贪婪的算法将做必要的。问题类似于找出给定列车时刻表所需的平台数量。因此,重叠的数量将是所需平台的数量
callStart时间排序。开始将每个调用放入一个数组(一个平台)。因此,对于调用i and (i + 1)
,如果callEnd[i] > callStart[i+1]
,则它们不能进入相同的数组(或平台),尽可能多地放入第一个数组中。然后用其余的重复该过程,直到所有呼叫都用完为止。最后,数组的数量是最大重叠数。而复杂性将是O(n)
。
答案 3 :(得分:1)
以下页面提供了使用多种语言解决此问题的示例:http://rosettacode.org/wiki/Max_Licenses_In_Use
答案 4 :(得分:0)
您缩短了CallStart
上的列表。然后,对于每个元素(i
),您会看到所有j < i
if
CallEnd[j] > CallStart[i] // put it in a map with CallStart[i] as the key and some count
休息应该很容易。
答案 5 :(得分:0)
令人惊讶的是,对于某些问题解决方案有时只会突然出现......而且我认为我可能是最简单的解决方案;)
您可以用范围(0)开始到结束(600)来表示以秒为单位的时间。电话是一对。
Python算法:
def maxSimultaneousCalls(calls):
"""Returns the maximum number of simultaneous calls
calls : list of calls
(represented as pairs [begin,end] with begin and end in seconds)
"""
# Shift the calls so that 0 correspond to the beginning of the first call
min = min([call[0] for call in calls])
tmpCalls = [(call[0] - min, call[1] - min) for call in calls]
max = max([call[1] for call in tmpCalls])
# Find how many calls were active at each second during the interval [0,max]
seconds = [0 for i in range(0,max+1)]
for call in tmpCalls:
for i in range(call[0],call[1]):
seconds[i] += 1
return max(seconds)
请注意,我目前不知道哪些电话有效;)
但就复杂性而言,评估非常简单:它在呼叫总持续时间方面是线性的。
答案 6 :(得分:0)
我认为解决这个问题的一个重要因素是识别每个结束时间是&gt; =呼叫的开始时间以及开始时间是否有序。因此,不要考虑阅读整个列表和排序,我们只需要按照开始时间顺序读取并从结束时间的最小堆中合并。这也解决了Sanjeev关于如何在开始之前处理结束的评论,当它们具有完全相同的时间值时,通过从结束时间最小堆轮询并且当它的值是<=下一个开始时间时选择它。
max_calls = 0
// A min-heap will typically do the least amount of sorting needed here.
// It's size tells us the # of currently active calls.
// Note that multiple keys with the same value must be supported.
end_times = new MinHeap()
for call in calls:
end_times.add(call.end)
while (end_times.min_key() <= call.start) {
end_times.remove_min()
}
// Check size after calls have ended so that a start at the same time
// doesn't count as an additional call.
// Also handles zero duration calls as not counting.
if (end_times.size() > max_calls) max_calls = end_times.size()
}
答案 7 :(得分:0)
这似乎是reduce
操作。类比是每次呼叫开始时,当前活动呼叫数增加1.每次呼叫结束时,当前呼叫数下降到零。
一旦有了这个活动呼叫流,您只需要对它们应用最大操作。这是一个有效的python2示例:
from itertools import chain
inp = ((123, 125),
(123, 130),
(123, 134),
(130, 131),
(130, 131),
(130, 132),)
# technical: tag each point as start or end of a call
data = chain(*(((a, 'start'), (b, 'end')) for a, b in inp))
def r(state, d):
last = state[-1]
# if a call is started we add one to the number of calls,
# if it ends we reduce one
current = (1 if d[1] == 'start' else -1)
state.append(last + current)
return state
max_intersect = max(reduce(r, sorted(data), [0]))
print max_intersect
答案 8 :(得分:0)
这是Python中的工作算法
def maximumOverlap(calls):
times = []
for call in calls:
startTime, endTime = call
times.append((startTime, 'start'))
times.append((endTime, 'end'))
times = sorted(times)
count = 0
maxCount = 0
for time in times:
if time[1] == 'start':
count += 1 # increment on arrival/start
else:
count -= 1 # decrement on departure/end
maxCount = max(count, maxCount) # maintain maximum
return maxCount
calls = [
('2:22:22 PM', '2:22:33 PM'),
('2:22:35 PM', '2:22:42 PM'),
('2:22:36 PM', '2:22:43 PM'),
('2:22:46 PM', '2:22:54 PM'),
('2:22:49 PM', '2:27:21 PM'),
('2:22:57 PM', '2:23:03 PM'),
('2:23:29 PM', '2:23:40 PM'),
('2:24:08 PM', '2:24:14 PM'),
('2:27:37 PM', '2:39:14 PM'),
('2:27:47 PM', '2:27:55 PM'),
('2:29:04 PM', '2:29:26 PM'),
('2:29:31 PM', '2:29:43 PM'),
('2:29:45 PM', '2:30:10 PM'),
]
print(maximumOverlap(calls))