查找最大的连续时间段

时间:2012-03-07 00:51:19

标签: php algorithm

我在某一天有一系列时间段,有些重叠,如此(开始,结束):

(10.00, 10.15) (11.00, 11.30) (11.30, 11.45) (11.45, 12.00) 
(11.45, 12.15) (12.15, 12.45) (13.20, 13.30) (14.15, 14.35) (14.35, 14.40)

我想找到最大的连续时间段。在上面的例子中有3组连续的时间(如下所示),但由于第一组是第二组的较小'替代',所以应该忽略它,所以我们留下2和3。

  1. 11.00 - 11.30,1130 - 11.45,11.45 - 12.00
  2. 11.00 - 11.30,1130 - 11.45,11.45 - 12.15,12.15 - 12.45
  3. 14.15 - 14.35,14.35 - 14.40
  4. 我必须补充一点:我希望能够指定一个'容差'来定义连续的含义。在上面的示例中,连续表示第一个时间段的结束时间==下一个时间段的开始时间,但将连续定义为“相隔5分钟”的时间段会更好。

    有关如何在php或伪代码中执行此操作的任何想法将非常感谢!

2 个答案:

答案 0 :(得分:2)

这感觉就像Dynamic Programming类问题。我想它也可以解决为图形问题。

如果您将数据转换为图形:每个周期都是一个顶点,如果它们是连续的,则连接两个顶点(使用您想要的任何容差级别)。所有边缘都具有相同的重量。现在,您需要在该图表上找到longest path

最长的路径问题是NP-complete,这是一个无赖。但是,对于没有周期的图形,可以在多项式时间内解决这个问题。凉。你的图表是一个循环的我希望(你不会整天徘徊,对吧?)。所以,只需在每条边上加上-1的权重,找到最短的图形。我提供的最后一个链接也有一个动态编程方法。

答案 1 :(得分:0)

这个问题有一个简单的greedy解决方案。首先按开始日期升序对时间段进行排序,如果相等,则按结束日期降序排序。现在循环遍历时间段并跟踪当前的集合(它是最左侧和最右侧的位置)。这是伪代码(或一些PHP / C ++ / JS混合) -

bool comp(A, B) {
    if(A.start == B.start) return A.end > B.end;
    return A.start < B.start;
}

function getLongestSet( periods ) { //convert the times to integer first, period is pair of integers
    sort ( periods, comp);
    longestPeriod = 0;
    for(i = 0; i < periods.length; i++) {
        if(periods[i].start > curRight + TOLERANCE) { //start new set
            curLeft = periods[i].start, curRight = periods[i].end;
        }
        else { //expand current set
            curRight = max(curRight, periods[i].end);
        } 
        longestPeriod = max(longestPeriod, curRight - curLeft);
    }
    return longestPeriod;
}