Как-то раз по поставленной задаче столкнулся я с проблемой, решения которой я в интернете так и не нашел. Либо проблема специфическая и никто с ней не сталкивался, либо она примитивная, а я использовал не те процедуры поиска. Но как и для любого программера мне стало интересно решить ее самому и своим способом…
Проблема заключалась вот в чем: есть к примеру 10 задач выполняющихся паралельно, каждая задача разбита на подзадачи которые стартуют в определенное время и известна их продолжительность, нам надо добавить в одну из задач пару подзадач, но в начале нужно узнать есть ли в заданом интервале свободные отрезки времени нужной нам продолжительности и со скольки до скольки они длятся. Мы имеем $reservArray с данными которые содержат в себе для каждого элемента масива время старта и окончания события, так же мы имеем время старта и окончания ($timeArray) промежутка в котором нам необходимо проверить какие промежутки и какой продолжительности у нас останутся если в заданом промежутке произойдут все события из пердыдущего массива.
Как результат мне было нужно чтоб функция вернула масив с свободными промежутками если они больше чем та продолжительность которую я передаю функции как параметр $duration, так же была добавлена переменная прогрешности для времени старта и окончания события, которая мне в тот момент была необходима чтобы отсечь промежутки не представляющие для меня интереса (меньше 3 сек)
в результате передачи данной функции всех параметров я получал на выходе масив промежутков времени свободных от событий и по продолжительности больше заданной в $duration
если будут вопросы — задавайте, но хотелось бы выслушать решение подобной проблемы другими способами. ;)
оригинал статьи в моем блоге на ЖЖ
P.S. если минусуете то хоть укажите что не понравилось, или у меня плохое настроение, давай и другим испорчу…
Человек решает проблему и предлагает ее решение другим, а кто-то втихую минусует и у него от этого настроение поднимается…
P.S.2 Вот тролли… хоть выскажите что не нравится, зачем просто так минусовать??? еще пару решений на Javascript и PHP есть, но даже и не знаю с такими тролями только мемуары тут писать можно, судя по оценке данного топика бесплатные решения тут не нравятся… по крайней мере высказываний за что минусы тут пару а минусов больше чем плюсов. есть ли смыл публиковаться дальше?
PPS благодаря MikhailEdoshin было найдено решение позволяющее заменить строки 46-52 на
за что ему отдельное спасибо!
Проблема заключалась вот в чем: есть к примеру 10 задач выполняющихся паралельно, каждая задача разбита на подзадачи которые стартуют в определенное время и известна их продолжительность, нам надо добавить в одну из задач пару подзадач, но в начале нужно узнать есть ли в заданом интервале свободные отрезки времени нужной нам продолжительности и со скольки до скольки они длятся. Мы имеем $reservArray с данными которые содержат в себе для каждого элемента масива время старта и окончания события, так же мы имеем время старта и окончания ($timeArray) промежутка в котором нам необходимо проверить какие промежутки и какой продолжительности у нас останутся если в заданом промежутке произойдут все события из пердыдущего массива.
Как результат мне было нужно чтоб функция вернула масив с свободными промежутками если они больше чем та продолжительность которую я передаю функции как параметр $duration, так же была добавлена переменная прогрешности для времени старта и окончания события, которая мне в тот момент была необходима чтобы отсечь промежутки не представляющие для меня интереса (меньше 3 сек)
function getFreeTimeArray($timeArray, $reservArray, $duration, $nullDuration = 3) {
$resultArray = null;
$tmpArray[] = $timeArray;
if (!empty($reservArray) && is_array($reservArray)) {
foreach ($reservArray as $value) {
if (!empty($tmpArray))
foreach ($tmpArray as $tmp_key => $tmp_val) {
/*
* reserved line
* a|============|b
*
* time line
* x|------------|y
*
*
* a = $value['start']
* b = $value['end']
*
* x = $tmp_val['start']
* y = $tmp_val['end']
*/
/* if x>a && x>b
*
* a|====|b
*
* x|------|y
*
*
* OR y
*
* a|====|b
*
* x|------|y
*
*
* => reserved & time line not intersect
*/
if (($tmp_val['start'] > $value['start'] && $tmp_val['start'] > $value['end'])
|| ($tmp_val['end'] < $value['start'] && $tmp_val['end'] < $value['end'])) {
} else {
//reserved & time line intersect
/* if x<=a && y>=b
*
* a|====|b
*
* x|------------|y
*
*/
if ($tmp_val['start'] <= $value['start'] && $tmp_val['end'] >= $value['end']) {
//if (a-x) > nullDuration -> save data to array('start'=>x,'end'=>(a-1))
if (($value['start'] - $tmp_val['start']) > $nullDuration)
$tmpArray[] = array('start' => $tmp_val['start'], 'end' => $value['start'] - 1);
//if (y-b) > nullDuration -> save data to array('start'=>(b+1),'end'=>y)
if (($tmp_val['end'] - $value['end']) > $nullDuration)
$tmpArray[] = array('start' => ($value['end'] + 1), 'end' => $tmp_val['end']);
//delete this time interval
unset($tmpArray[$tmp_key]);
}
/* if x>=a && y<=b
*
* a|==========|b
*
* x|------|y
*
*/
else if ($tmp_val['start'] >= $value['start'] && $tmp_val['end'] <= $value['end']) {
unset($tmpArray[$tmp_key]);
}
/* if x>=a && x<=b
*
* a|=====|b
*
* x|------------|y
*
*/ else if ($tmp_val['start'] >= $value['start'] && $tmp_val['start'] <= $value['end']) {
if (($tmp_val['end'] - $value['end']) > $nullDuration)
$tmpArray[] = array('start' => ($value['end'] + 1), 'end' => $tmp_val['end']);
unset($tmpArray[$tmp_key]);
}
/* if y>=a && y<=b
*
* a|=====|b
*
* x|----------|y
*
*/
else if ($tmp_val['end'] >= $value['start'] && $tmp_val['end'] <= $value['end']) {
if (($value['start'] - $tmp_val['start']) > $nullDuration)
$tmpArray[] = array('start' => $tmp_val['start'], 'end' => ($value['start'] - 1));
unset($tmpArray[$tmp_key]);
}
}
}
}
}
// if result is not null
// check duration in result data and sort array
if (!empty($tmpArray)) {
$tmpArray2 = null;
foreach ($tmpArray as $val) {
if ($duration <= ($val['end'] - $val['start']))
$tmpArray2[$val['start']] = $val;
}
ksort($tmpArray2);
$tmpArray = $tmpArray2;
}
$resultArray = $tmpArray;
return $resultArray;
}
в результате передачи данной функции всех параметров я получал на выходе масив промежутков времени свободных от событий и по продолжительности больше заданной в $duration
если будут вопросы — задавайте, но хотелось бы выслушать решение подобной проблемы другими способами. ;)
оригинал статьи в моем блоге на ЖЖ
P.S. если минусуете то хоть укажите что не понравилось, или у меня плохое настроение, давай и другим испорчу…
Человек решает проблему и предлагает ее решение другим, а кто-то втихую минусует и у него от этого настроение поднимается…
P.S.2 Вот тролли… хоть выскажите что не нравится, зачем просто так минусовать??? еще пару решений на Javascript и PHP есть, но даже и не знаю с такими тролями только мемуары тут писать можно, судя по оценке данного топика бесплатные решения тут не нравятся… по крайней мере высказываний за что минусы тут пару а минусов больше чем плюсов. есть ли смыл публиковаться дальше?
PPS благодаря MikhailEdoshin было найдено решение позволяющее заменить строки 46-52 на
if($tmp_val['start'] < $value['end'] && $value['start'] < $tmp_val['end'])
за что ему отдельное спасибо!