0

我目前正在尝试为 Game Kami制定计划。因此我需要用 PDDL 语言创建一个域和问题。

卡米规则:

规则很简单。您可以使用与您指定的颜色相同的颜色为一个图块和所有相邻图块着色。该调用是recusive,因此相邻瓦片的邻居也将获得相同的颜色。

目标:

通过使用上述递归函数,所有图块应具有相同的颜色。

我已经被卡米的 2x2 世界困住了,在这里你可以看到我的...

... 领域:

(define (domain kami-dom)
    (:requirements :strips :typing :disjunctive-preconditions :negative-preconditions :conditional-effects)

    (:types c - tile
            brown red green - color
    )

    (:predicates
        (color_value ?t - tile ?c - color)
        (is_neighbour ?t ?sec_t - tile)
    )

    (:action color_tile
        :parameters (?t - tile ?old_c ?new_c - color)
        :precondition (and (not (color_value ?t ?new_c)) (color_value ?t ?old_c))
        :effect (and
            (forall (?acc - tile) 
                (when (and (is_neighbour ?t ?acc) (color_value ?acc ?old_c)) 
                    (and (color_value ?acc ?new_c) (not (color_value ?acc ?old_c)))
                )
            )
            (color_value ?t ?new_c)
            (not (color_value ?t ?old_c))
        )
    )
)

...和我的Problem.pddl:

(define (problem kami-prob-x-1)
   (:domain kami-dom)

   (:objects
      tile11 tile12 tile21 tile22 - tile
      red green brown - color)

   (:init
      (color_value tile11 red)
      (color_value tile12 red)
      (color_value tile21 red)
      (color_value tile22 brown)

      (is_neighbour tile11 tile12)
      (is_neighbour tile11 tile21)

      (is_neighbour tile12 tile11)
      (is_neighbour tile12 tile22)

      (is_neighbour tile21 tile11)
      (is_neighbour tile21 tile22)
      
      (is_neighbour tile22 tile12)
      (is_neighbour tile22 tile21)
   )
   
   (:goal (or   (and (color_value tile11 red) (color_value tile12 red) (color_value tile21 red) (color_value tile22 red))
                (and (color_value tile11 green) (color_value tile12 green) (color_value tile21 green) (color_value tile22 green))
                (and (color_value tile11 brown) (color_value tile12 brown) (color_value tile21 brown) (color_value tile22 brown)))))

而且我无法获得成功的计划,即使它只应用了一次功能color_tile

4

2 回答 2

0

关于你的问题如何使这个递归。我想你想要的是让你的一个动作为以前颜色为 A 的文件着色为颜色 B 也为颜色 A 的“区域”中的所有图块着色为颜色 B。这通常称为Floodfill。问题是 PDDL 效果在其基本版本中并不真正支持这种递归。相反,您可以使用多个操作对递归进行编码。

你可以做的,就是将 Floodfill 分成三个步骤:开始、传播、结束。对于每个步骤,您可以创建单独的操作。其他谓词可用于跟踪您当前正在填充的颜色以及已填充的图块。我已经修改了你的域和问题来做到这一点(见下文)。

当您执行转弯时,您执行start_color操作(color_tile 不适用)。它为一个图块着色并将(a)当前颜色设置为该图块具有的旧颜色,并且(b)将此图块标记为当前着色。之后,可以使用color_tile操作传播此着色。着色以done_color动作结束。之后,start_color可以执行另一个动作。使用 FastDownward(和盲 A* 搜索),您可以获得以下最佳计划:

start_color tile25 brown green (1)
color_tile tile25 tile22 brown green (1)
color_tile tile22 tile23 brown green (1)
color_tile tile22 tile24 brown green (1)
done_color  (1)
start_color tile11 red green (1)
color_tile tile11 tile12 red green (1)
color_tile tile11 tile21 red green (1)
done_color  (1)

注意:此建模可能不完全符合您的需要。问题是您可以为相邻的瓷砖着色,但您不必这样做。您可以对此进行编码(最后done_color),但我想这会很乏味。

领域:

(define (domain kami-dom)
(:requirements :strips :typing :disjunctive-preconditions :negative-preconditions :conditional-effects)

(:types tile color)

(:predicates
    (color_value ?t - tile ?c - color)
    (currently_colored ?t - tile)
    (current_color ?c - color)
    (is_neighbour ?t ?sec_t - tile)
)

 
(:action start_color
    :parameters (?t - tile ?old_c ?new_c - color)
    :precondition (and 
        (forall (?ot - tile) (not (currently_colored ?ot)))
        (not (color_value ?t ?new_c)) (color_value ?t ?old_c)
    )
    :effect (and
        (color_value ?t ?new_c)
        (not (color_value ?t ?old_c))
        (currently_colored ?t)
        (current_color ?old_c)
    )
)


(:action color_tile
    :parameters (?old_t ?new_t - tile ?old_c ?new_c - color)
    :precondition (and (not (color_value ?new_t ?new_c)) (color_value ?new_t ?old_c) (color_value ?old_t ?new_c) (currently_colored ?old_t) (current_color ?old_c))
    :effect (and
        (color_value ?new_t ?new_c)
        (not (color_value ?new_t ?old_c))
        (currently_colored ?new_t)
    )
)


(:action done_color
    :parameters ()
    :effect (and
        (forall (?t - tile) (not (currently_colored ?t)))
        (forall (?c - color) (not (current_color ?c)))
    )
)
)

问题:

(define (problem kami-prob-x-1)
(:domain kami-dom)

(:objects
   tile11 tile12 tile21 tile22 tile23 tile24 tile25 - tile
  red green brown - color)

(:init
  (color_value tile11 red)
  (color_value tile12 red)
  (color_value tile21 red)
  (color_value tile22 brown)
  (color_value tile23 brown)
  (color_value tile24 brown)
  (color_value tile25 brown)

  (is_neighbour tile11 tile12)
  (is_neighbour tile11 tile21)

  (is_neighbour tile12 tile11)
  (is_neighbour tile12 tile22)

  (is_neighbour tile21 tile11)
  (is_neighbour tile21 tile22)
  
  (is_neighbour tile22 tile12)
  (is_neighbour tile22 tile21)
  
  (is_neighbour tile22 tile23)
  (is_neighbour tile23 tile22)

  (is_neighbour tile23 tile24)
  (is_neighbour tile24 tile23)

  (is_neighbour tile24 tile25)
  (is_neighbour tile25 tile24)
)

(:goal (and (color_value tile11 green) (color_value tile12 green) (color_value tile21 green) (color_value tile22 green) (color_value tile23 green) (color_value tile24 green) (color_value tile25 green)
            (forall (?t - tile) (not (currently_colored ?t)))
            )
 )
 )
于 2020-10-12T17:08:22.393 回答
0

问题出在域文件中的 :types 描述中。您应该将其替换为:

(:types tile color)

之后,如果您运行一些计划器,它将返回一个有效的计划。例如,我使用了 Fast Downward ( http://www.fast-downward.org/ ) 并得到以下输出(我删除了一些不相关的部分):

color_tile tile11 red brown (1)
[t=0.00733501s, 9896 KB] Plan length: 1 step(s).
[t=0.00733501s, 9896 KB] Plan cost: 1
[t=0.00733501s, 9896 KB] Expanded 2 state(s).

所以它确实找到了一个包含绘制 tile11 的单一动作的计划。

于 2020-10-09T13:46:09.100 回答