确切的问题覆盖algorithmist。
贪婪sweep line样式算法算法将最优解决您的问题。
假设您希望先覆盖尽可能多的非不相交区域,然后在给定第一个约束的情况下使用最少数量的区域,然后该算法将在O(n^2)时间内为您解决问题。
其基本思想是按照从上到下的顺序进行,只有当你是“裸体”的时候才拿一段,即没有覆盖给定的部分。当你不得不参加一个部分时,把最能够覆盖你的部分放到'未来'中。这个实现是O(n^2),但是可以通过更好地管理cand来使其成为O(n log(n))。
#!/usr/bin/python
START_EVENT, END_EVENT = 0, 1 # handle starts before ends at same point
def max_future(cands):
return max(cands, key=lambda c: (c[1], c)[1])
def cover_max_segment_min(intervals):
events = []
for interval in intervals:
events.append((interval[0], START_EVENT, interval))
events.append((interval[1], END_EVENT, interval))
cands = []
outputs = []
alive = None
# Handle events by
# event time,
# starts before ends,
# longer endings before shorter endings
events.sort(key=lambda x: (x[0], x[1], -x[2][1]))
for k, event_type, interval in events:
if event_type == START_EVENT:
cands.append(interval)
if event_type == END_EVENT:
cands.remove(interval)
if interval is alive:
alive = None
if not alive and cands:
outputs.append(max_future(cands))
alive = outputs[-1]
return outputs
assert cover_max_segment_min([(0, 3), (1, 4), (3, 5)]) == \
[(0, 3), (3, 5)]
assert cover_max_segment_min([(0, 3), (3, 5), (1, 4)]) == \
[(0, 3), (3, 5)]
assert cover_max_segment_min([(0, 3)]) == [(0, 3)]
assert cover_max_segment_min([]) == []
assert cover_max_segment_min([(-10, 10), (1, 2), (3, 5)]) == [(-10, 10)]
assert cover_max_segment_min([(1, 2), (2, 3), (3, 4)]) == \
[(1, 2), (2, 3), (3, 4)]
assert cover_max_segment_min([(1, 4), (1, 2), (3, 3)]) == \
[(1, 4)]
@Tim,裁剪的部分是否重叠或是否是唯一的? – Kiril 2011-06-13 19:07:14
他们肯定会重叠。事实上,会有很多重叠,这就是为什么尽量减少使用的部分数量非常重要。 – Tim 2011-06-13 19:15:49
@Tim,酷,所以如果你采取贪婪的方法,并采取最少的重叠裁剪部分,这样可以吗? – Kiril 2011-06-13 19:31:20