понедельник, 7 марта 2011 г.

Повторяемые задания

Встретился с интересной задачкой.
Есть список некоторых заданий. Что это за задания нам не интересно, главное что они как-то распределены во времени.
Существуют два типа заданий:
  • разовые;
  • повторяемые.
Каждое из них, думаю, допустимо описать парой: (дата окончания, паттерн повторяемости), где:
  • дата окончания - дата, до которой данное задание должно быть выполнено, включительно;
  • паттерн повторяемости - шаблон по которому создаются новые задания. Задание разовое - пуст, повторяемое - имеет свою структуру:
    • тип повторяемости - один из вариантов: 'ежедневно', 'еженедельно', 'ежемесячно', 'ежегодно';
    • повторять через - число дней/недель/месяцев/годов;
    • длительность задания - d-дней, m-месяцев, y-лет.
Думаю с разовыми заданиями все очевидно, задание необходимо выполнить до указанной даты окончания,  больше оно нас не будет тревожить. Что же касается повторяемых заданий, то тут есть проблемы.
На самом деле, повторяемое задание - это одно разовое задание, которое нужно выполнить до указанной даты окончания и шаблон по которому будут созданы новые разовые задания. Вопросы, связанные с повторяемыми заданиями, которые нас будут интересовать:
  1. Как определить, необходимо ли сегодня (DD.MM.YY) создавать новое разовое задание для некоторого повторяемого ? Будем считать, что задание может быть создано за 1 день до официального начала.
  2. Как назначить дату окончания нового разового задания ?

Прежде чем переходить к ответу на эти вопросы для общей задачи, давайте придумаем примеры повторяемых заданий, т.е. таких пар (дата окончания, паттерн повторяемости), и попытаемся ответить на эти вопросы для них.

Примеры заданий

Задание 1
дата окончания: 15.02.11
повторять: каждый 1 месяц
длительность: 1 месяц

Предварительные замечания:
Если дата окончания - 15.02.11 и длительность 1 месяц => начало задание - 15.01.11.

Пусть сегодня: 13.02.11.
  1. Так как 15.01.11 + 1 месяц > 13.02.11 + 1 день => ещё рано;
  2. -

Пусть сегодня: 16.02.11.
  1. Так как 15.01.11 + 1 месяц <= 16.02.11 + 1 день => можно начинать;
  2. Так как повторяемость - 1 месяц => дата окончания нового задания - 15.02.11 + 1 месяц = 15.03.11.

Пусть сегодня: 14.03.11.
  1. Так как 15.03.11 + 1 месяц <= 14.03.11 + 1 день => можно начинать;
  2. Так как повторяемость - 1 месяц => дата окончания нового задания - 15.03.11 + 1 месяц = 15.03.11.

Задание 2
дата окончания: 15.02.11
повторять: каждый 1 год
длительность: 2 дня и 3 месяца

Предварительные замечания:
Если дата окончания - 15.02.11 и длительность 2 дня и 3 месяц => начало задания - 13.11.10.

Пусть сегодня: 16.02.11.
  1. Так как 13.11.10 + 1 год > 16.02.11 + 1 день => ещё рано;
  2. -

Пусть сегодня: 12.11.11.
  1. Так как 13.11.10 + 1 год <= 12.11.11 + 1 день => можно начинать;
  2. Так как повторяемость - 1 год => дата окончания нового задания - 15.02.11 + 1 год = 15.02.12.

Пусть сегодня: 12.11.12.
  1. Так как 13.11.11 + 1 год <= 12.11.11 + 1 день => можно начинать;
  2. Так как повторяемость - 1 год => дата окончания нового задания - 15.02.12 + 1 год = 15.02.13.

Алгоритмы решения
Пусть:
Сегодня: D1.M1.Y1
дата окончания: D0.M0.Y0 (первого задания)
дата окончания: D2.M2.Y2 (предыдущего задания)
повторять: каждый A день/неделю/месяц/год
длительность: d-дней, m-месяцев, y-лет.

Алгоритм 1
То что первое пришло в голову. Давайте будем действовать также, как мы решали задачки в примерах. Т.е. принимать решение о создании нового задания на основе данных о прошлой разовой задаче, созданной по шаблону данной повторяемой.
Тогда:
  1. Если D1.M1.Y1 + 1 день >= D2.M2.Y2 - (d + m + y) + A => можно начинать, иначе ещё рано;
  2. Дата окончания нового задания - D2.M2.Y2 + A.
Ок, это будет работать, но только в том случае, если мы можем сохранять последнюю разовую задачу, т.е. каждый раз мы должны знать D2.M2.Y2, что не всегда возможно.

Алгоритм 2
Здесь я предполагаю описать алгоритм, который бы не зависел от предыдущей задачи, и которому было бы достаточно только даты окончания первого задания и паттерна повторяемости.

Комментариев нет:

Отправить комментарий