定期间隔

时间:2013-08-15 11:34:38

标签: intervals period

我的代码中有以下结构:

class Interval {
    public $start, $end;
}

class Period {
    public $interval, $period;
}

它们分别代表一个简单的重复间隔。例如:

**** // This is a simple interval [0, 4].
****__****__**** // This is "repeating interval" with period = 2 (each underline means pause between intervals)

因此,周期是一组无限的间隔。它们之间的“距离”(或暂停)是不变的。

我需要一个接受任意间隔和周期的函数,并说明此间隔是否在句点内。 “内部”意味着给定的间隔在期间的任何间隔内。

function interval_inside_period(Interval $interval, Period $period) {
  return is_inside ? true : false;
}

$period = new Period(new Interval(0, 4), 10); 
// The first 3 intervals in this Period are [0, 4], [14, 18] and [28, 32]
// Like: ****__________****__________****
interval_inside_period(new Interval(15, 16), $period); // === true, is inside [14, 18]
interval_inside_period(new Interval(29, 32), $period); // === true, is inside [28, 32]
interval_inside_period(new Interval( 3,  5), $period); // === false, overlaps but is not inside
interval_inside_period(new Interval(17, 29), $period); // === false, overlaps but is not inside
interval_inside_period(new Interval(11, 12), $period); // === false
interval_inside_period(new Interval(20, 27), $period); // === false

问题是由于缺乏数学经验,我不知道如何实现这样的功能。我已经考虑了wave函数,特别是关于rectangular periodic function,但我不知道如何用这样的函数描述Period。

Square wave function

可以描述具有相同长度和周期的简单周期
$square_period = new Period(new Interval(0, 2), 2);
// __**__**__**__**
// This function describes such Period.
function is_square_period($n) {
    return ($n >= 0 && ($n / 2) % 2) == 0 ? 1 : 0;
}

这种方法有机会查找是否有任何整数$ n存在于Period内。但我不知道这是否可以用来解决问题。

有什么想法吗?提前谢谢。

1 个答案:

答案 0 :(得分:1)

让我们看看......两个连续间隔之间的偏移是$start + $end + $period。因此,时间间隔k的开头位于k * ($start + $end + $period) + $start。通过将x从给定的时间间隔(new Interval(x, y))除以$start + $end + $period,我们可以计算出k

// this is should be integer division...
$k = ($interval->start - $period->interval->start)
    / ($period->interval->start + $period->interval->end + $period->period);

现在我们可以计算区间k的界限,并检查给定的区间是否在其中。

$kStart = $k * (
        $period->interval->start + $period->interval->end + $period->period
    ) + $period->interval->start;
$kEnd = $kStart + ($period->interval->end - $period->interval->start);

return $kStart <= $interval->start && interval->end <= $kEnd;

这会产生以下内容,包括您问题的句点和第一个间隔:

$k = (15 - 0) / (0 + 4 + 10) = 15 / 14 = 1
$kStart = 1 * (0 + 4 + 10) + 0 = 1 * 14 + 0 = 14
$kEnd = 14 + (4 - 0) = 18

return (14 <= 15 && 16 <= 18) // true

剩余间隔的值为:

iStart | iEnd | k | kStart | kEnd | result
-------+------+---+--------+------+-------
    29 |   32 | 2 |     28 |   32 | true
     3 |    5 | 0 |      0 |    4 | false
    17 |   29 | 1 |     14 |   18 | false
    11 |   12 | 0 |      0 |    4 | false
    20 |   27 | 1 |     14 |   18 | false