Algorithm 查找时间范围列表中的重叠(数量)
给定一个时间范围列表,我需要找到重叠的最大数量 以下是显示10分钟通话间隔的数据集,从 我正试图找出其中活动线的最大数量 间隔例如,从下面的示例中,同时处于活动状态的最大呼叫数是多少:Algorithm 查找时间范围列表中的重叠(数量),algorithm,Algorithm,给定一个时间范围列表,我需要找到重叠的最大数量 以下是显示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
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
如果有人知道一个故事或者能给我指出正确的方向,我
我将不胜感激
蒂亚
Steve F一个天真的方法怎么样:
- 取最小的开始时间和最大的结束时间(这是您的范围R)
- 取最短的呼叫持续时间--d(排序,O(nlog n))
- 创建一个包含ceil(R/d)整数的数组C,初始化为零
- 现在,对于每个调用,在定义调用持续时间O(n*ceil(R/d))的单元格中添加1
- 循环数组C并保存最大值(O(n))
numberOfCalls
设置为0(计数变量)- 如果时间值标记为开始,则增加numberOfCalls
- 如果时间值标记为结束,则减少numberOfCalls
- 跟踪过程中numberOfCalls的最大值(以及发生时的时间值)
复杂性:O(n log(n))用于排序,O(n)用于遍历所有记录您可以在
调用开始
上缩短列表。然后对于每个元素(i
),您可以看到所有j
如果
CallEnd[j] > CallStart[i] // put it in a map with CallStart[i] as the key and some count
Rest应该足够简单。在我看来,贪婪算法将完成需要的工作。问题类似于找出给定列车时刻表所需的站台数量。因此,重叠的数量将是所需的平台数量。
呼叫开始时间已排序。开始将每个调用放入一个数组(一个平台)。因此,对于call
i和(i+1)
,如果callEnd[i]>callStart[i+1]
,则它们不能进入同一数组(或平台),在第一个数组中放入尽可能多的调用。然后对rest-one重复这个过程,直到所有调用都用尽。最后,数组的数量是重叠的最大数量。而复杂性将是O(n)
令人惊讶的是,对于某些问题,解决方案有时只是从一个头脑中蹦出来。。。我想我可能是最简单的解决方案;)
您可以以秒为单位表示时间,从范围的开始(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)
请注意,我不知道此时哪些呼叫处于活动状态;)
但就复杂性而言,评估它是极其简单的:就呼叫的总持续时间而言,它是线性的。下页有许多语言解决此问题的示例:我认为解决此问题的一个重要因素是认识到每个结束时间都是>=呼叫的开始时间,并且开始时间是有序的。因此,我们不需要考虑整个列表的读取和排序,而只需要按照开始时间的顺序读取,并从结束时间的最小堆中合并。这也解决了Sanjeev关于当结束时间最小值堆具有完全相同的时间值时,应如何在开始之前处理结束的评论,方法是轮询结束时间最小值堆,并在其值为max_calls时选择它)max_calls=end_times.size() }
这似乎是一个
减少操作。类似地,每次启动呼叫时,当前活动呼叫数都会增加1。每次通话结束时,当前的通话次数将降至零
一旦有了活动调用流,您所需要的就是对它们应用max操作。下面是一个工作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
下面是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))
的确很简单,我发布了另一个不需要排序的解决方案,我想知道它在性能方面的表现如何……如何跟踪numberOfCalls的最大值?@ygnhzeus,将其保存在一个单独的变量中,并在当前numberOfCalls值大于以前的maximumIt遗漏一个用例时更新它。假设在精确的一个点上有多个起点和终点,即假设在2:25:00有2个起点和3个终点。因此,排序后的范围间隔将在2:25:00有5个值,以随机顺序开始2次,结束3次。但要使algo正常工作,结束应该先于开始。@vladimir非常好而且清晰的解决方案,Thnks。但是,如果我们想返回所有的重叠时间,而不是重叠的数量,该怎么办?再次感谢
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))