问题描述
我目前正在尝试为游戏Kami创建计划。因此,我需要使用PDDL语言创建一个域和问题。
卡米规则:
规则很简单。您可以使用与设置相同的颜色为一个图块和所有相邻图块上色。该呼叫具有回响性,因此相邻图块的邻居也将获得相同的颜色。
目标:
使用上述递归功能,所有图块应具有相同的颜色。
我已经被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 函数,我也无法获得成功的计划。
解决方法
问题出在域文件中的: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的单个动作的计划。
,关于您的问题如何进行此递归。我想您想做的是使您以前为颜色B中的颜色A的文件着色的操作,也可以为颜色B中的颜色A“区域”中的所有图块着色。这通常称为{{3} }。问题在于,PDDL效果在其基本版本中实际上并不支持这种递归。相反,您可以使用多个操作对递归进行编码。
您可以做的是将洪水填充分为三个步骤:开始,传播,结束。对于每个步骤,您都可以创建一个单独的操作。可以使用其他谓词来跟踪当前填充的颜色以及填充的瓷砖。我已经修改了您的域和问题来做到这一点(见下文)。
进行转弯时,将执行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)))
)
)
)