嗯,我觉得很难解释,所以我已经做了一个数字来表明这一点。
正如我们在该图中所看到的,有6个时间间隔。每个人都有自己的体重。不透明度越高,重量越高。我想要一个算法来找到具有最高总重量的区间。在图的情况下,它是间隔5和6的重叠,这是不透明度最高的区域。
答案 0 :(得分:5)
将每个间隔分成开始点和结束点。
对点进行排序。
以0的总和开始。
如果你有一个起点:
将总和增加相应间隔的值。
如果总和数高于目前为止的最佳总和,请存储此起点并设置一个标志。
如果你得到一个终点:
如果设置了该标志,则存储存储的起点和此终点,并将当前总和作为最佳间隔,并重置该标志。
将计数减去相应间隔的值。
这是源自the answer I wrote here,它基于未加权版本,即找到重叠间隔的最大数量,而不是最大总重量。
示例:强>
对于这个例子:
起点/终点的排序方式为:(S
= start,E
= end)
1S, 1E, 2S, 3S, 2E, 3E, 4S, 5S, 4E, 6S, 5E, 6E
通过它们进行迭代,您可以在1S
,5S
和6S
上设置标记,然后将相应的区间存储在1E
,4E
和5E
(这是您在上述起点之后获得的第一个终点)。
您不会在2S
,3S
或4S
上设置标记,因为总和将低于目前为止的最佳总和。
答案 1 :(得分:1)
算法逻辑可以从图中导出。假设时间间隔的分辨率为1分钟,则可以创建一个数组并用于所有计算:
如果您需要在输出中包含区间索引,则可以针对略有不同的任务修改此算法。在这种情况下,数组应该包含输入时间间隔索引的列表作为第二个维度(或者它可以是一个单独的数组,具体取决于特定的语言)。
UPD。我很好奇这个简单的算法是否比@Dukeling建议的更优雅的算法慢得多。我编写了两种算法并创建了一个输入生成器来估计它们的性能。
发电机:
#!/bin/sh
awk -v n=$1 '
BEGIN {
tmax = 24 * 60; wmax = 100;
for (i = 0; i < n; i++) {
t1 = int(rand() * tmax);
t2 = int(rand() * tmax);
w = int(rand() * wmax);
if (t2 >= t1) {print t1, t2, w} else {print t2, t1, w}
}
}' | sort -n > i.txt
算法#1:
#!/bin/sh
awk '
{t1[++i] = $1; t2[i] = $2; w[i] = $3}
END {
for (i in t1) {
for (t = t1[i]; t <= t2[i]; t++) {
W[t] += w[i];
}
}
Wmax = 0.;
for (t in W){
if (W[t] > Wmax) {Wmax = W[t]}
}
print Wmax;
for (t in W){
if (W[t] == Wmax) {print t}
}
}
' i.txt > a1.txt
算法#2:
#!/bin/sh
awk '
{t1[++i] = $1; t2[i] = $2; w[i] = $3}
END {
for (i in t1) {
p[t1[i] "a" i] = i "S";
p[t2[i] "b" i] = i "E";
}
n = asorti(p, psorted, "@ind_num_asc");
W = 0.; Wmax = 0.; f = 0;
for (i = 1; i <= n; i++){
P = p[psorted[i] ];
k = int(P);
if (index(P, "S") > 0) {
W += w[k];
if (W > Wmax) {
f = 1;
Wmax = W;
to1 = t1[k]
}
}
else {
if (f != 0) {
to2 = t2[k];
f = 0
}
W -= w[k];
}
}
print Wmax, to1 "-" to2
}
' i.txt > a2.txt
结果:
$ ./gen.sh 1000
$ time ./a1.sh
real 0m0.283s
$ time ./a2.sh
real 0m0.019s
$ cat a1.txt
24618
757
$ cat a2.txt
24618 757-757
$ ./gen.sh 10000
$ time ./a1.sh
real 0m3.026s
$ time ./a2.sh
real 0m0.144s
$ cat a1.txt
252452
746
$ cat a2.txt
252452 746-746
$ ./gen.sh 100000
$ time ./a1.sh
real 0m34.127s
$ time ./a2.sh
real 0m1.999s
$ cat a1.txt
2484719
714
$ cat a2.txt
2484719 714-714
简单的开启速度要慢20倍。