连续跨度是什么样的剂量?
连续跨度由元组(start, end)
表示。
例如,(2, 8)
指的是一个从2开始并以8结尾的区域。
最广泛的覆盖范围是什么意思?
对于跨度列表,例如[(0, 4), (2, 8), (5, 10), (6, 9)]
,堆积结果将是:
│ 0......4
│ 2...........8
│ 5.........10
│ 6.....9
└────────────────────────
0 1 2 3 4 5 6 7 8 9 10 ...
跨度最深的覆盖范围是(6, 8)
,即3。
在这种情况下,预期收益应为(6,8)
我的解决方案
我不知道如何表示连续跨度,因此,我将每个连续跨度分解为数字列表,并尝试从计数器结果中找到最常见的一个。
from collections import Couter
import numpy as np
density = Counter()
for start, end in SPAN_LIST:
density.update(
np.round(np.arange(start, end, 0.01)), 2)
)
most_dense_site, most_dense_count = density.most_common()[0]
结果可能不准确,并且对于大量列表(大约数十亿个项目)而言,速度非常慢。 我知道,如果提高精度,结果将更加准确,但同时也会浪费更多的内存。
我想知道如何加快流程并以更好的方式使结果更准确吗?
答案 0 :(得分:1)
详细介绍评论部分:
解决方案是遍历范围的所有起点和终点,将它们混合在一起,以便“扫过”这些点。我们将考虑这些事件,并跟踪当前访问的范围。由范围开始触发的事件将增加当前访问范围的计数。范围结束触发的事件将减少当前访问范围的数量。
(下面的代码假定范围是半开的,包括开始但不结束。)
def deepest_coverage(span_list):
if not span_list:
raise ValueError("The given list must be non-empty")
events = []
for start, end in span_list:
events.append((start, 1))
events.append((end, -1))
events.sort()
ret = None
most_visited = currently_visited = 0
for i in range(len(events)):
currently_visited += events[i][1]
if currently_visited > most_visited:
most_visited = currently_visited
ret = events[i][0], events[i+1][0]
return ret
print(deepest_coverage([(0, 4), (2, 8), (5, 10), (6, 9)]))
输出:
(6, 8)
资源:
答案 1 :(得分:0)
我用Python中的扫描线算法编写了此解决方案。
跨度列表并展平为“位置列表”,起点和终点的身份按分数记录。
合并相邻的起点和终点,以提高性能并修复错误的位置错误。
循环显示位置列表并记录其得分最深的范围。
from collections import defaultdict
def get_deepest_coverage(span_list):
"""Get the span with the deepest coverage."""
pos_dict = defaultdict(int)
for start, end in span_list:
pos_dict[start] += 1
pos_dict[end] -= 1
pos_list = sorted((k, v) for k, v in pos_dict.items() if v)
deepest_start = deepest_end = None
deepest_count = current_count = 0
for index, (pos, score) in enumerate(pos_list):
current_count += score
if current_count > deepest_count:
deepest_count = current_count
deepest_start, deepest_end = pos, pos_list[index + 1][0]
return deepest_start, deepest_end, deepest_count
print(get_deepest_coverage([(2, 8), (5, 7), (7, 20)]))
感谢@miloszlakomy提供的所有材料。还有不错的解决方案。
(我花了整个下午写这篇摘要,发现@miloszlakomy在这里发布了答案。)
感谢xxx一直拒绝我的帖子全部,否则我将没有动力自己解决这个问题。