PDDL - Коза, Волк и Капуста
Меня попросили написать решение для знаменитого скернарио "Коза, волк и капуста". Сценарий выглядит следующим образом:
Фермер хочет перевезти всех троих через реку. Однако если:
- Козу и капусту оставляют в покое, козочка съест капусту
- Если волк и козел останутся одни, волк съест козу!
Итак, одно решение проблемы заключается в следующем:
- Возьми козу через реку и брось ее на другую сторону
- Вернись через реку
- Возьмите ЛИБО капусту или волка и перенесите на другую сторону
- Оставь волка, возьми козу и возвращайся на другую сторону
- Оставьте козу, возьмите капусту и вернитесь на другую сторону
- Возьми козу и вуаля! Все три перевозятся.
Однако у меня возникли проблемы с проецированием этого на PDDL. Я дал определение проблемы:
(define
(problem boat1)
(:domain boat)
; only needs two objects, namely representing
; either banke side of the river, [w]est and [e]ast
(:objects w e)
(:INIT
; wolf, goat, cabbage, boat are all on
; the west side to start with
(config w w w w)
; represent all valid states
; these two are the special case,
; representing that wolf and cabbage are
; safe together even if the boat is away
(valid w e w e)
(valid e w e w)
; these are all cases where two entities
; are always safe as long as the boat is
; with them. In other words, a single entity
; on the other side is also always safe
; for west side
(valid w w w w)
(valid w w e w)
(valid w e w w)
(valid e w w w)
; for east side
(valid e e e e)
(valid e e w e)
(valid e w e e)
(valid w e e e)
; these are all valid states that are
; ever allowed
)
(:goal (AND
; they all have to move to the east side
(config e e e e)
)
)
Наконец, нам дали только 1 предикат, и нам сказали, что это можно сделать с помощью 4 действий. Move_empty, move_goat, move_wolf, move_cabbage.
Предикат:
(config? волк? коза? капуста? лодка) (действительный? волк? коза? капуста? лодка)
и я попытался начать на move_empty с:
(:action move_empty
:parameters (?from ?to)
:precondition (and (valid ?x ?y ?z ?w) (on_left ?from) (on_right ?to))
:effect (and (valid ?x ?y ?z ?w)))
Я не желаю ответов, а только помощи и советов о том, как решить эту проблему, так как информации по PDDL не так много, из того, что я могу найти.
1 ответ
ПРИМЕЧАНИЕ: я не знаю язык pddl, это то, чего я достиг, посмотрев на ваш код.
СМЫСЛ
В вашей задаче каждая сущность описывается как находящаяся на западном или восточном берегу реки, и сущности идентифицируются с использованием их относительного положения в конфигурации предикатов и действительны.
Каждое действие начинается с данной конфигурации и должно заканчиваться другой конфигурацией. Кроме того, мы должны требовать, чтобы конечная конфигурация была действительной.
Так что move_empty с востока на западную сторону банка так же просто, как:
(:action move_empty_ew :parameters (?x ?y ?z)
:precondition (and (config ?x ?y ?z e) (valid ?x ?y ?z w))
:effect (and (not (config ?x ?y ?z e)) (config ?x ?y ?z w))
)
Здесь мы позволяем неопределенным позициям всех других объектов (волка, козла и капусты), в то время как мы требуем, чтобы изначально лодка находилась на восточном берегу и чтобы лодка отправлялась на западный берег, оставляя животных без присмотра - действительный ход. Если все эти условия соблюдены, то мы переходим к желаемой конфигурации.
РЕШЕНИЕ
Обратите внимание, что я уточнил название действий, чтобы они были более информативными по отношению к. фактическое действие, которое предпринимается.
Лодка-domain.pddl
(define (domain boat)
(:requirements :equality)
(:predicates
(config ?wolf ?goat ?cabbage ?boat)
(valid ?wolf ?goat ?cabbage ?boat)
)
(:action move_empty_ew :parameters (?x ?y ?z)
:precondition (and (config ?x ?y ?z e) (valid ?x ?y ?z w))
:effect (and (not (config ?x ?y ?z e)) (config ?x ?y ?z w))
)
(:action move_empty_we :parameters (?x ?y ?z)
:precondition (and (config ?x ?y ?z w) (valid ?x ?y ?z e))
:effect (and (not (config ?x ?y ?z w)) (config ?x ?y ?z e))
)
(:action move_wolf_ew :parameters (?y ?z)
:precondition (and (config e ?y ?z e) (valid w ?y ?z w))
:effect (and (not (config e ?y ?z e)) (config w ?y ?z w))
)
(:action move_wolf_we :parameters (?y ?z)
:precondition (and (config w ?y ?z w) (valid e ?y ?z e))
:effect (and (not (config w ?y ?z w)) (config e ?y ?z e))
)
(:action move_goat_ew :parameters (?x ?z)
:precondition (and (config ?x e ?z e) (valid ?x w ?z w))
:effect (and (not (config ?x e ?z e)) (config ?x w ?z w))
)
(:action move_goat_we :parameters (?x ?z)
:precondition (and (config ?x w ?z w) (valid ?x e ?z e))
:effect (and (not (config ?x w ?z w)) (config ?x e ?z e))
)
(:action move_cabbage_ew :parameters (?x ?y)
:precondition (and (config ?x ?y e e) (valid ?x ?y w w))
:effect (and (not (config ?x ?y e e)) (config ?x ?y w w))
)
(:action move_cabbage_we :parameters (?x ?y)
:precondition (and (config ?x ?y w w) (valid ?x ?y e e))
:effect (and (not (config ?x ?y w w)) (config ?x ?y e e))
)
)
Лодка-prob.pddl
(define (problem boat)
(:domain boat)
(:objects w e)
(:INIT (config w w w w)
(valid w e w e) (valid e w e w)
(valid w w w w) (valid w w e w)
(valid w e w w) (valid e w w w)
(valid e e e e) (valid e e w e)
(valid e w e e) (valid w e e e)
)
(:goal (config e e e e))
)
Я использовал fast-downward, чтобы найти решение минимальной длины:
~$ fast-downward.py --alias seq-opt-bjolp boat-domain.pddl boat-prob.pddl
что на самом деле является:
move_goat_we w w (1)
move_empty_ew w e w (1)
move_cabbage_we w e (1)
move_goat_ew w e (1)
move_wolf_we w e (1)
move_empty_ew e w e (1)
move_goat_we e e (1)
Plan length: 7 step(s).
Plan cost: 7