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
Другие вопросы по тегам