我有一个重叠间隔的排序列表,间隔从不相互包含,例如,
[(7, 11), (9, 14), (12, 17)]
输出的约束是使每个元素尽可能接近它 原点(间隔的中间),保留输入的顺序,并删除所有重叠。只有一个 近似解是必要的。示例输入的预期结果是:
[(5,9), (9, 14), (14, 19)]
我只知道某些模拟中的解决方案 style:在自由方向上将每个元素移动一些值 迭代直到所有重叠都被删除。
是否有现成的算法来解决这个问题?
答案 0 :(得分:2)
找到整体平均值:
在我们的示例中:
(7 + 11 + 9 + 14 + 12 + 17)/6 = 11.667
找到总长度:
(11-7) + (14-9) + (17-12) = 4 + 5 + 5 = 14;
找到新的min / max;
14/2 = 7
11.667 - 7 = 4.667
11.667 + 7 = 18.667
你可以围绕他们
4.667 ~ 5
18.667 ~ 19
从min开始,按间隔
创建部分(5, (11-7)+5) = (5,9)
(9, (14-9)+9) = (9,14)
(14, (17-12)+14) = (14,19)
注:
此方法不会使元素尽可能与原始元素保持一致,但会考虑它们的相对值(保留中心)使它们尽可能接近原始值
修改强>
如果你想让所有区间的平均值尽可能接近原始区间,你可以实现一个数学解决方案。
我们的问题输入是:
a 1 =(a 1,1 , 1,2 ),..., n 子> =(A <子> N,1 子>,一个<子> N,2 子>)
我们将定义:
ai 1 = a 1,2 -a 1,1 //定义间隔
b 1 =(d,d + ai 1 )
b n =(d + sum(ai 1 .. ai n-1 ),d + sum(ai 1 .. ai n ))
bi 1 = b 1,2 -b 1,1 //定义间隔
我们需要找到一个'd',例如:
s = sum(abs((a 1,1 + a 1,2 )/ 2 - (b 1,1 + b 1,2 )/ 2))
min(s)是我们想要的
在我们的示例中:
a 1 =(7,11),ai 1 = 4,A avg1 = 9
a 2 =(9,14),ai 2 = 5,A avg2 = 11.5
a 3 =(12,7),ai 3 = 5,A avg3 = 14.5
b 1 =(d,d + 4)B avg1 = d + 2
b 2 =(d + 4,d + 9)B avg2 = d + 6.5
b 3 =(d + 9,d + 14)B avg3 = d + 11.5
s = abs(9-(d + 2))+ abs(11.5-(d + 6.5))+ abs(14.5-(d + 11.5))= abs(7-d)+ abs(5-d )+ abs(3-d)
现在计算导数以找到min / max OR 迭代d以获得结果。在我们的例子中,你需要从3到7迭代
应该做的伎俩
答案 1 :(得分:0)
鉴于解决方案必须是保持顺序的,我们可以将此问题表述为线性程序。设[a i ,b i ]为第i个间隔。设变量x i 是第i个区间的左移,y i 是第i个区间的右移。
最小化和 i (x i + y i )
受制于
(*)对于所有i:b i - x i + y i ≤a i + 1 - x i + 1 + y i + 1
对于所有i:x i ,y i ≥0
通过引入变量z i 重写约束(*)。
对于所有i:x i - y i - x i + 1 + y i + 1 - z i = 0
对于所有i:z i ≥b i - a i + 1
现在问题已经减少到计算minimum-cost circulation,这可以在多时间内完成。但是,我有一种感觉,就是可以更直接地解决这个问题。
图表类似于
(*)
---- | ----
/ z| \
/ i| \
/ xi | xi+1 \
|/ <---- v <---- \|
... (*) ...
----> ---->
yi yi+1