用PDDL实现骑士之旅

本文介绍了如何使用Planning Domain Definition Language(PDDL)解决经典的骑士之旅问题。内容包括问题的状态表示、动作定义以及8x8棋盘上的有效骑士移动。通过Python程序生成336个动作,并展示了PDDL实现的域文件和问题文件,利用VSCode中的PDDL插件进行演示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注意:本节内容参考《An Introduction to the Planning
Domain Definition Language》

骑士之旅是一个经典的国际象棋难题。在国际象棋中,骑士棋子沿任何基本方向(水平或垂直)移动两个空格,然后沿垂直方向移动一个空格。

与其他棋子不同,骑士“跳”到目标位置而不踩中间方块。骑士之旅是骑士的一系列动作,使棋子可以访问棋盘的每一个方块,而不必两次踩在任何方块上。(因此,它是哈密顿路径问题的一个特例。)下图显示了骑士从棋盘左上角开始的巡游示例。
骑士之旅

问题状态可以表示为一组事实(骑士棋子所在的位置,以及它已经访问过的方块),计划由一系列动作(骑士的动作)组成,这些动作将起始状态(棋子处于起始位置,没有访问过其他方块)转换为满足目标条件的最终状态(参观过每个方块)。必须制定行动,以便它们捕获问题的所有约束:特别是,每个行动不仅必须对应于有效的骑士移动,而且还必须强制要求移动的目标方块尚未访问。

在域文件中我们定义了动作move以及三个谓词at、visited、valid_move,对于8*8的方格,棋盘上有336个有效骑士移动。因此,我们可以通过编写336个像这样的动作来模拟这个谜题,使用64个谓词表示骑士可能的当前位置,使用64个谓词跟踪访问的方块。这336个动作我们利用python程序生成:

# 这里代码感觉有点繁琐,大家有好的建议可以联系我修改
lists = [[0] * 8 for i in range(8)]
for i in range(1, 9):
    for j in range(1, 9):
        lists[i - 1][j - 1] = chr((ord('A') + i - 1)) + str(j)
        # print("(visited " + lists[i-1][j-1] + ")")

actions = []
for i in range(8):
    for j in range(8):
        if i + 2 < 8 and j + 1 < 8:
            actions.append("(valid_move " + lists[i][j] + " " + lists[i + 2][j + 1] + ")")

for i in range(8):
    for j in range(8):
        if i + 2 < 8 and -1 < j - 1 < 8:
            actions.append("(valid_move " + lists[i][j] + " " + lists[i + 2][j - 1] + ")")
for i in range(8):
    for j in range(8):
        if i + 1 < 8 and j + 2 < 8:
            actions.append("(valid_move " + lists[i][j] + " " + lists[i + 1][j + 2] + ")")
for i in range(8):
    for j in range(8):
        if i + 1 < 8 and -1 < j - 2 < 8:
            actions.append("(valid_move " + lists[i][j] + " " + lists[i + 1][j - 2] + ")")
for i in range(8):
    for j in range(8):
        if -1 < i - 2 < 8 and -1 < j - 1 < 8:
            actions.append("(valid_move " + lists[i][j] + " " + lists[i - 2][j - 1] + ")")
for i in range(8):
    for j in range(8):
        if -1 < i - 2 < 8 and j + 1 < 8:
            actions.append("(valid_move " + lists[i][j] + " " + lists[i - 2][j + 1] + ")")
for i in range(8):
    for j in range(8):
        if -1 < i - 1 < 8 and -1 < j - 2 < 8:
            actions.append("(valid_move " + lists[i][j] + " " + lists[i - 1][j - 2] + ")")
for i in range(8):
    for j in range(8):
        if -1 < i - 1 < 8 and j + 2 < 8:
            actions.append("(valid_move " + lists[i][j] + " " + lists[i - 1][j + 2] + ")")

# for i in actions:
#     print(i)

然后,下面是我们用PDDL语言实现的域文件和问题文件:

;这里是域文件
(define (domain knights-tour)
    (:requirements :negative-preconditions)

    (:predicates
        (at ?square)
        (visited ?square)
        (valid_move ?square_from ?square_to)
    )

    (:action move
        :parameters (?from ?to)
        :precondition (and (at ?from)
                            (valid_move ?from ?to)
                            (not (visited ?to))
        )
        :effect (and (not(at ?from))
                    (at ?to)
                    (visited ?to)
        )
    )    
)
;这里是我们的问题文件
(define (problem knights-tour-problem-8x8)
    (:domain knights-tour)

    (:objects
        A1 A2 A3 A4 A5 A6 A7 A8 
        B1 B2 B3 B4 B5 B6 B7 B8 
        C1 C2 C3 C4 C5 C6 C7 C8 
        D1 D2 D3 D4 D5 D6 D7 D8 
        E1 E2 E3 E4 E5 E6 E7 E8 
        F1 F2 F3 F4 F5 F6 F7 F8 
        G1 G2 G3 G4 G5 G6 G7 G8 
        H1 H2 H3 H4 H5 H6 H7 H8
    )

    (:init
        ; 我们假设骑士在右上角
        (at A8)
        (visited A8)
        ;我们罗列出所有的有效动作
        (valid_move A1 C2)
        (valid_move A2 C3)
        (valid_move A3 C4)
        (valid_move A4 C5)
        (valid_move A5 C6)
        (valid_move A6 C7)
        (valid_move A7 C8)
        (valid_move B1 D2)
        (valid_move B2 D3)
        (valid_move B3 D4)
        (valid_move B4 D5
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值