2013-08-15 5 views
2
내 코드에서 다음과 같은 구조를 가지고

는 :주기적인 간격으로

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 

문제는 수학적 경험이 부족하여 그러한 기능을 구현하는 방법을 모르는 것입니다. 나는 특히 웨이브 함수에 대해 생각 해왔다. 특히 rectangular periodic function에 대해서 생각해 봤지만, 그런 기능을 가진 마침표를 어떻게 기술해야하는지 전혀 모른다.

같은 길이와주기와 간단한 기간은 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은 기간 안에 여부를 낳는 경우 찾을 수있는 기회를 제공합니다. 그러나 이것이 문제를 해결하는 데 사용될 수 있는지는 알 수 없습니다.

아이디어가 있으십니까? 미리 감사드립니다.

답변

1

두 개의 연속 간격 사이의 오프셋은 $start + $end + $period입니다. 따라서 간격 k의 시작은 k * ($start + $end + $period) + $start입니다. 간격 k

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

이제 우리는 계산할 수 경계 주어진 간격이 그 안에 있는지 확인 : $start + $end + $period하여 지정된 간격 ( new Interval(x, y))에서 x을 나눔으로써 우리는 우리의 k을 계산할 수 있습니다. 나머지 구간에 대한

$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 
$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; 

은 기간과 질문의 첫 번째 간격으로 다음을 산출
관련 문제