d9e5a92d

Программа планирования мероприятий






Ниже приведена программа планирования мероприятий, написанная на языке CLIPS. При сформировании расписания программа сначала старается как можно раньше назначить для каждого отдельного мероприятия начальный момент выполнения, а затем назначает конечный момент, если в расписании найдено место для мероприятия. Программа расставляет задачи в соответствии с их приоритетами и старается сохранять себе свободу действий как можно дольше. Однако эта программа не способна справиться с ситуацией, которая складывается после неудачно принятого решения, ни с помощью обратного прослеживания, ни с помощью коррекции частичного расписания, из которого развился тупиковый вариант.

;; ШАБЛОНЫ

;; Объект мероприятий.

(deftemplate errand

(field name (type SYMBOL)) ; имя

;; интервал времени, в течение которого нужно

;; приступить к выполнению мероприятия



;; не раньше (field earliest (type INTEGER) (default 0))

;; не позже

(field latest (type INTEGER) (default 0))

;; продолжительность

(field duration (type INTEGER) (default 0))

;; приоритет

(field priority (type INTEGER) (default 0))

;; включено в расписание (field done (type SYMBOL)

(default no));

)

; ; Объект расписания (def template schedule

(field task (type SYMBOL))

;; задача

;; интервал времени, в течение которого нужно

;; выполнить задачу

;; начало

(field start (type INTEGER) (default 0))

;; конец

(field finish (type INTEGER) (default 0))

;; приоритет

(field priority (type INTEGER) (default 0))

;; полностью заполнено

(field status (type SYMBOL) (default no))

)

;; Объект цели. Используется для управления поведением

;; программы, принуждая ее к определенному порядку

;; достижения целей. (def template goal

(field subgoal (type SYMBOL)))

;; ФАКТЫ

(deffacts the-facts (goal (subgoal start))

(errand (name hospital) (earliest 1030)

(latest 1030)

(duration 200) (priority 1)) (errand

(namе doctor) (earliest 1430) (latest 1530)

(duration 200) (priority 1))

(errand (name lunch) (earliest 1130) (latest 1430)

(duration 100) (priority 2))

(errand (name guitar-shop)

(earliest 1000)

(latest 1700) (duration 100)

(priority 3)) (errand (name haircut)

(earliest 900) (latest 1700)

(duration 30) (priority 4))

(errand (name groceries)

(earliest 900) (latest 1800)

(duration 130) (priority 5))

(errand (name dentist)

(earliest 900) (latest 1600)

(duration 100) (priority 2))

;; Попадает ли время начала S в интервал [Т, T+D]?

;; Две задачи не могут начинаться в одно и то же время.

(deffunction overlapl (Is ?t ?d)

(and (<= ?t ?s) (< ?s (+ ?t ?d))))

;; Попадает ли время завершения S в интервал [Т, T+D]?

;; Для задачи А можно назначить время начала выполнения

;; равным времени завершения задачи В.

(deffunction overlap2 (?s ?t ?d)

(and (< ?t ?s) (< ?s (+ ?t ?d))))

;; Операция добавления к значению времени интервала,

;; выраженного в формате INTEGER,

(deffunction +t (?X ?Y) (bind ?T (+ ?X n))

(if(or (= (- ?T 60) ( (div (- ?T 60) 100) 100))

(= (- ?T 70) ( (div (- ?T 70) 100) 100))

(= (- ?T 80) ( (div (- ?T 80) 100) 100))

(= (- ?T 90) ( (div (- ?T 90) 100) 100)))

then (+ ?T 40)

telse ?T))

;; ПРАВИЛА

;; На выполнение некоторых задач отводится

;; фиксированное время, (defrule fixed

(declare (salience 80))

(goal (subgoal start))

?E <- (errand (name ?N)

(earliest ?T) (latest ?T) (duration ?D)

(priority ?P) (done no))

(not (schedule (start ?U1&:(overlapl ?U1 ?T ?D))))

(not (schedule (finish ?U2&:(overlap2 ?U2 ?T ?D))))

(printout t crlf "Fixing start and end of " ?N t crlf)

;; ( "Определение начала и завершения " ?N

(modify ?E (done finish)) (assert (schedule (task ?N)

(start ?T) (finish (+t ?T ?D)) (priority ?P)))

;; Следующей в расписание включается задача с наиболее

;; высоким приоритетом, причем ей задается самое раннее

;; время начала выполнения, (defrule priorityl

(declare (salience 50))

(goal (subgoal start))

: ?Е <- (errand (name ?N) (earliest ?T)

(duration ?D) (priority ?P)) (not (errand

(priority ?Q&:(< ?Q ?P)) (done no)))

(not (schedule (start ?01&:(overlapl ?Ul ?T ?D))))

(not (schedule (finish ?U2S:(overlap2 ?U2 ?T ?D))) =>

(printout t crlf "Fixing start of " ?N t crlf)

;;"Коррекция начала: " ?N

(modify ?E (done start)) (assert (schedule

(task ?N) (start ?T) (priority ?P)

)

;; Скорректировать значение параметра earliest задач

;; более низкого приоритета, если это время уне занято

;; теми задачами, которые включены в расписание,

(defrule priority2

(declare (salience 60))

(goal {subgoal start)) ?E <- (errand (name ?N)

(earliest ?T)(duration ?D) (priority ?P) (done no))

(not (errand (priority ?QS:(< ?Q ?P)') (done no)))

(schedule (task ?M) (start ?U&:(overlapl 7U ?T ?D)))

(errand (name ?M&~?N) (duration ?C)) =>

(printout t crlf ?N " overlaps with start of " ?M t crlf)

;; ?N " пересекается с началом " ?M

(modify ?E (earliest (+t ?U ?C))) )

;; Скорректировать значение параметра earliest задач

;; более низкого приоритета, если запуск задачи в

;; указанное этим параметром время приведет к тому,

;; что она не успеет завершиться до запуска другой

;; задачи более высокого приоритета,

;; ухе включенной в расписание,

(defrule priority3

(declare (salience 60))

(goal (subgoal start))

?E <- (errand (name ?N) (earliest ?T)

(priority ?P) (done no))

(errand (name ?M&"?N) (duration ?C))

(schedule (task ?M)

(start ?0&:(overlap1 ?T ?U ?C)))

(printout t crlf ?N " overlaps with end of " ?M t crlf)

;; ?N " пересекается с концом " ?M

(modify ?E (earliest (+t ?U ?C)))

)

;;Скорректировать значение параметра earliest

;; задач более низкого приоритета,

;;если запуск задачи в указанное этим

;;параметром время приведет к тому,

;; что ее начало перекроет одну

;;задачу, уже включенную

;; ранее в расписание, и она не успеет завершиться

;; до запуска другой задачи более высокого приоритета ,

;; уже включенной в расписание.

(defrule priority4

(declare (salience 60))

(goal (subgoal start))

?E <- (errand (name.?N) (earliest ?T)

(duration ?D) (priority ?P) (done no))

(errand (name ?M&~?N) (duration ?C))

(schedule (task ?M)

(start ?U&:(<= ?U ?T)) (finish ?F&:

(<= (+ ?T ?D) ?F)))

)

=>

(printout t crlf ?N " would

occur during " ?M t crlf)

?N " может появиться во время "

?М (modify ?E (earliest (+t ?U ?C)))

)

;; Изменение цели. Новая цель - установка конечного

;; времени выполнения задачи. (defrule change-goal

?G <- (goal (subgoal start)) =>

(modify ?G (subgoal finish))

)

;; Время завершения задачи - это время начала ее

;; выполнения плюс продолжительность . (defrule endpoint

(goal (subgoal finish))

(errand (name ?N) (latest ?L) (duration ?D))

?S <- (schedule (task ?N) (start

?!&:(<= ?T ?L)) (finish 0)) ... =>

(printout t crlf "Fixing end of" ?N t crlf)

;; "Определение завершения " ?N

(modify ?S (finish (+t ?T ?D)))

;; Новая цель - вывести отчет о плане.

(defrule unfinish

?G <- (goal (subgoal finish)) =>

(modify ?G (subgoal report))

)

;; Вывести задачи в хронологическом порядке.

(defrule scheduled

(declare (salience 10)) (goal (subgoal report))

?S <- (schedule (task ?N) (start ?T1) (finish ?T2S"0)

( status 0 ) ) . '(not (schedule (start ?T

3&:(<= ?T3 ?T1)) (status 0)))

)

=>

(printout t crlf ?N " from " ?T1 " till " ?T2t crlf)

;; ?N " от " ?T1 " до " ?T2

(modify ?S (status 1))

)


;; Для некоторых задач в расписании может не найтись

;; места.

(defrule unscheduled

(goal (subgoal report))

?S <- (schedule (task ?N) (finish 0) (status 0))

(printout t crlf ?N " not scheduled. " t crlf)

;; ?N " не включена в расписание. "

(modify ?S (status 1)) )

Эта программа успешно справляется с составлением расписания мероприятий, перечисленных после оператора deffact. В упр. 4 в конце главы будет показано, что существуют наборы мероприятий, с которыми программа не может справиться, хотя составить расписание для них с учетом оговоренных ограничений можно.



Содержание раздела