- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我现在遇到了一个算法问题,我想优化它的复杂性。
我有两个区间列表S = [[s1, s2], [s3, s4], ..., [sn-1, sn]]
和W = [[w1, w2], [w3, w4], ..., [wm-1, wm]]
要按照顺序合并,s的区间优先于w的区间(s表示强,w表示弱)。
例如,这一优先权意味着:S = [[5,8]]
和W = [[1, 5], [7, 10]]
将给出:res = [[1, 4, W], [5, 8, S], [9, 10, W]]
。这里从w开始的间隔优先于s的间隔S = [[5, 8]]
和W = [[2, 10]]
将给出:res = [[2, 4, W], [5, 8, S], [9, 10, W]]
。这里W的间隔被分成两部分,因为S有优先权。
在合并这些列表时,我需要通过在每个间隔旁边写入第三个元素(我们可以称之为符号)来跟踪这些间隔的强弱性质这就是为什么结果是这样的:[[1,4,w],[5,8,s],[9,10,w]]。
最后,由于所有间隔的并集不覆盖某个范围内的所有整数,因此我们有第三个符号,例如b表示空白,填充缺少的间隔:[[1, 2, W], [5, 8, S], [9, 10, W], [16, 20, S]]
将被填充为:[1, 2, W], [3, 4, B], [5, 8, S], [9, 10, W], [11, 15, B], [16, 20, S]]
我的第一次尝试是非常幼稚和懒惰(因为我首先想让它发挥作用):
如果这两个区间列表中包含的最大整数是m,那么我创建了一个m大小的列表,其中填充了b个符号:res = [B]*M = [B, B, B ..., B]
然后,我首先从w开始一个接一个地取间隔,并在此间隔中重写索引res中的元素,将其符号更改为w。接下来,我对间隔s执行相同的操作,并且由于在最后一步中用符号s覆盖,因此优先权得到尊重。
它给出了如下信息:[B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B]
[B, B, B, W, W, W, W, B, W, W, W, W, B, W, W, B, B]
[B, B, S, S, W, W, W, B, S, S, W, W, B, S, W, B, B]
最后,我最后一次遍历大列表,将间隔分解并用相应的符号重新创建间隔。前面的示例给出:[[1, 2, B], [3, 4, S], [5, 7, W], [8, 8, B], [9, 10, S], [11, 12, W], [13, 13, B], [14, 14, S], [15, 15, W], [16, 17, B]]
不幸的是,可预见的是,这个算法在实际中是不可用的:在我的应用程序中,m大约是1000000,如果我没有弄错的话,这个算法是o(n2)。
所以,我想一些建议和方向来解决这个算法复杂性问题。我确信这个问题看起来像是一个著名的算法问题,但我不知道该怎么办。
我的一些改进的想法现在可以用来优化算法,但是实现起来相当复杂,所以我认为有更好的想法但它们在这里:
执行相同的覆盖过程以尊重优先级:在列表w中,在需要尊重优先级时插入带覆盖的s间隔。然后填写此列表,用B符号插入缺少的间隔。但是,由于案例太多,我们会大量使用if来比较间隔。
在逐步浏览S和W的同时构造一个新列表在这个想法中,我们将有一个逐列表光标从一个间隔转到另一个间隔,直到两个列表中的一个结束再次,我们使用了很多if和case,我们在新列表中插入了优先级的间隔。但在大量的案件中,这也提出了同样复杂的问题。
我希望我说得很清楚,如果不是的话,我可以用另一种方式来解释。
请教我经验和智慧:)
谢谢
编辑:这是我的“天真”算法代码:
def f(W, S, size):
#We first write one symbol per sample
int_result = ['B'] * size
for interval in W:
for i in range(interval[0], interval[1]+1):
int_result[i] = 'W'
for interval in S:
for i in range(interval[0], interval[1]+1):
int_result[i] = 'S'
#we then factorize: we store one symbol for an interval of the same symbol.
symbols_intervals = []
sym = int_result[0]
start = 0
for j in range(len(int_result)):
if int_result[j] != sym:
symbols_intervals.append([start, j-1, sym])
sym = all_symbols[j]
start = j
if j == len(int_result)-1:
symbols_intervals.append([start, j-1, sym])
return symbols_intervals
最佳答案
你幼稚的方法听起来很合理,我认为它的时间复杂度是O(nm),其中n是你试图解决的间隔数,m是你试图解决的区间。你可能遇到的困难是,你还有O(m)的空间复杂度,这可能会占用一段相当长的内存。
这里有一种合并的方法,而不需要构建一个“主列表”,这可能更快,因为它把间隔视为对象,复杂性不再与M联系在一起。
我将一个区间(或区间列表)表示为一组元组(a,b,p)
,每个元组指示从a
到b
的时间点,包括整数优先级p
(W
可以是1
,而S
可以是2
)在每个间隔中,必须是a
b
的情况。优先考虑更高的优先级。
我们需要一个谓词来定义两个区间之间的重叠:
def has_overlap(i1, i2):
'''Returns True if the intervals overlap each other.'''
(a1, b1, p1) = i1
(a2, b2, p2) = i2
A = (a1 - a2)
B = (b2 - a1)
C = (b2 - b1)
D = (b1 - a2)
return max(A * B, D * C, -A * D, B * -C) >= 0
def join_intervals(i1, i2):
'''
Joins two intervals, fusing them if they are of the same priority,
and trimming the lower priority one if not.
Invariant: the interval(s) returned by this function will not
overlap each other.
>>> join_intervals((1,5,2), (4,8,2))
{(1, 8, 2)}
>>> join_intervals((1,5,2), (4,8,1))
{(1, 5, 2), (6, 8, 1)}
>>> join_intervals((1,3,2), (4,8,2))
{(1, 3, 2), (4, 8, 2)}
'''
if has_overlap(i1, i2):
(a1, b1, p1) = i1
(a2, b2, p2) = i2
if p1 == p2:
# UNION
return set([(min(a1, a2), max(b1, b2), p1)])
# DIFFERENCE
if p2 < p1:
(a1, b1, p1) = i2
(a2, b2, p2) = i1
retval = set([(a2, b2, p2)])
if a1 < a2 - 1:
retval.add((a1, a2 - 1, p1))
if b1 > b2 + 1:
retval.add((b2 + 1, b1, p1))
return retval
else:
return set([i1, i2])
merge_intervals
取一定的间隔并将它们连接在一起,直到不再有重叠:
import itertools
def merge_intervals(intervals):
'''Resolve overlaps in an iterable of interval tuples.'''
# invariant: retval contains no mutually overlapping intervals
retval = set()
for i in intervals:
# filter out the set of intervals in retval that overlap the
# new interval to add O(N)
overlaps = set([i2 for i2 in retval if has_overlap(i, i2)])
retval -= overlaps
overlaps.add(i)
# members of overlaps can potentially all overlap each other;
# loop until all overlaps are resolved O(N^3)
while True:
# find elements of overlaps which overlap each other O(N^2)
found = False
for i1, i2 in itertools.combinations(overlaps, 2):
if has_overlap(i1, i2):
found = True
break
if not found:
break
overlaps.remove(i1)
overlaps.remove(i2)
overlaps.update(join_intervals(i1, i2))
retval.update(overlaps)
return retval
merge_intervals
适用于您的示例:
# example 1
assert (merge_intervals({(5, 8, 2), (1, 5, 1), (7, 10, 1)}) ==
{(1, 4, 1), (5, 8, 2), (9, 10, 1)})
# example 2
assert (merge_intervals({(5, 8, 2), (2, 10, 1)}) ==
{(2, 4, 1), (5, 8, 2), (9, 10, 1)})
# example 3 (with B)
assert (merge_intervals([(1, 2, 1), (5, 8, 2), (9, 10, 1),
(16, 20, 2), (1, 20, 0)]) ==
{(1, 2, 1), (3, 4, 0), (5, 8, 2),
(9, 10, 1), (11, 15, 0), (16, 20, 2)})
关于python - 合并两个间隔列表,其中一个列表具有优先级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44155727/
这是代码片段。 请说出这种用小内存存储大数据的算法是什么。 public static void main(String[] args) { long longValue = 21474836
所以我使用 imap 从 gmail 和 outlook 接收电子邮件。 Gmail 像这样编码 =?UTF-8?B?UmU6IM69zq3OvyDOtc68zrHOuc67IG5ldyBlbWFpb
很久以前就学会了 C 代码;想用 Scheme 尝试一些新的和不同的东西。我正在尝试制作一个接受两个参数并返回两者中较大者的过程,例如 (define (larger x y) (if (> x
Azure 恢复服务保管库有两个备份配置选项 - LRS 与 GRS 这是一个有关 Azure 恢复服务保管库的问题。 当其驻留区域发生故障时,如何处理启用异地冗余的恢复服务保管库?如果未为恢复服务启
说,我有以下实体: @Entity public class A { @Id @GeneratedValue private Long id; @Embedded private
我有下一个问题。 我有下一个标准: criteria.add(Restrictions.in("entity.otherEntity", getOtherEntitiesList())); 如果我的
如果这是任何类型的重复,我会提前申请,但我找不到任何可以解决我的具体问题的内容。 这是我的程序: import java.util.Random; public class CarnivalGame{
我目前正在使用golang创建一个聚合管道,在其中使用“$ or”运算符查询文档。 结果是一堆需要分组的未分组文档,这样我就可以进入下一阶段,找到两个数据集之间的交集。 然后将其用于在单独的集合中进行
是否可以在正则表达式中创建 OR 条件。 我正在尝试查找包含此类模式的文件名列表的匹配项 第一个案例 xxxxx-hello.file 或者案例二 xxxx-hello-unasigned.file
该程序只是在用户输入行数时创建菱形的形状,因此它有 6 个 for 循环; 3 个循环创建第一个三角形,3 个循环创建另一个三角形,通过这 2 个三角形和 6 个循环,我们得到了一个菱形,这是整个程序
我有一个像这样的查询字符串 www.google.com?Department=Education & Finance&Department=Health 我有这些 li 标签,它们的查询字符串是这样
我有一个带有静态构造函数的类,我用它来读取 app.config 值。如何使用不同的配置值对类进行单元测试。我正在考虑在不同的应用程序域中运行每个测试,这样我就可以为每个测试执行静态构造函数 - 但我
我正在寻找一个可以容纳多个键的容器,如果我为其中一个键值输入保留值(例如 0),它会被视为“或”搜索。 map, int > myContainer; myContainer.insert(make_
我正在为 Web 应用程序创建数据库,并正在寻找一些建议来对可能具有多种类型的单个实体进行建模,每种类型具有不同的属性。 作为示例,假设我想为“数据源”对象创建一个关系模型。所有数据源都会有一些共享属
(1) =>CREATE TABLE T1(id BIGSERIAL PRIMARY KEY, name TEXT); CREATE TABLE (2) =>INSERT INTO T1 (name)
我不确定在使用别名时如何解决不明确的列引用。 假设有两个表,a 和 b,它们都有一个 name 列。如果我加入这两个表并为结果添加别名,我不知道如何为这两个表引用 name 列。我已经尝试了一些变体,
我的查询是: select * from table where id IN (1,5,4,3,2) 我想要的与这个顺序完全相同,不是从1...5,而是从1,5,4,3,2。我怎样才能做到这一点? 最
我正在使用 C# 代码执行动态生成的 MySQL 查询。抛出异常: CREATE TABLE dump ("@employee_OID" VARCHAR(50)); "{"You have an er
我有日期 2016-03-30T23:59:59.000000+0000。我可以知道它的格式是什么吗?因为如果我使用 yyyy-MM-dd'T'HH:mm:ss.SSS,它会抛出异常 最佳答案 Sim
我有一个示例模式,它的 SQL Fiddle 如下: http://sqlfiddle.com/#!2/6816b/2 这个 fiddle 只是根据 where 子句中的条件查询示例数据库,如下所示:
我是一名优秀的程序员,十分优秀!