DLS 深度受限搜索 狼羊 过河 问题 python 实现

2023-11-04

深度受限搜索(DLS)简单地说就是深度有限搜索(DFS)+深度限制(limit)

 

DLS伪代码

 

实例:狼羊 过河 问题

 

3只羊和3头狼在河岸A,想要过河抵达河岸B。它们只有一艘船并且船上必须有1-2只生物。当

任意一边的狼的数量大于羊时,羊会被吃光(fail)。初始状态为(3,3,1,0,0,0),意为3头羊

,3头狼和一艘船在河岸A,而河岸B没有羊,没有狼,也没有船。算法程序要达成的目标是(

0,0,0,3,3,1),意为3头羊,3头狼和一艘船都从河岸A抵达了河岸B。请用深度受限搜索(

Depth-Limited-Search)完成这份python程序,受限深度为15。

思路:

action是所有的操作方法,递归的时候在每个节点都要判断从它延伸的其他以下节点是否符合所需要的操作。然后再加上递归的深度限制,就可以解决。

代码1:

# -*- coding: utf-8 -*-
# Python版本:3.6



# 已探索集合
_explored = []

action = [[0, -1, 0], [0, -2, 0], [-1, 0, 0], [-2, 0, 0], [-1, -1, 0], [0, 1, 1], [0, 2, 1], [1, 0, 1], [2, 0, 1], [1, 1, 1]]

# 节点数据结构
class Node:
    def __init__(self, state, parent, action):
        self.state = state
        self.parent = parent
        self.action = action





def main():
    global _explored

    src_state=[3,3,1,0,0,0]
    dst_state=[0,0,0,3,3,1]
    limit=15

    result = depth_limited_search(src_state, dst_state, limit)
    if result == "failure" or result == "cutoff":
        print('from src_state: %s to dst_state %s search failure' % (src_state, dst_state))
    else:
        print('from src_state: %s to dst_state %s search success' % (src_state, dst_state))
        path = []
        while True:
            path.append(result.state)
            if result.parent is None:
                break
            result = result.parent
        size = len(path)
        for i in range(size):
            if i < size - 1:
                print('%s->' % path.pop(), end='')
            else:
                print(path.pop())


def depth_limited_search(src_state, dst_state, limit):
    global _explored
    _explored = []
    node = Node(src_state, None, None)
    return recursive_dls(node, dst_state, limit)


def recursive_dls(node, dst_state, limit):
    """
        :param node:
        :param dst_state:
        :param limit:
        :return: "failure":失败."cutoff":被截至.node:成功
        """
    global _explored

    if node.parent is not None:
        print('node state:%s parent state:%s' % (node.state, node.parent.state))
    else:
        print('node state:%s parent state:%s' % (node.state, None))
    _explored.append(node.state)

    # 目标测试
    if node.state == dst_state:
        print('this node is goal!')
        return node
    elif limit == 0:
        print('this node is cutoff!')
        return "cutoff"
    else:
        cutoff_occurred = False

        # 遍历子节点
        for state in action:
            if node.state[5] == state[2] and (node.state[1] + state[1]) >= 0 and (
                    node.state[1] + state[1]) <= 3 \
                    and (node.state[0] + state[0]) >= 0 and (node.state[0] + state[0]) <= 3:
                left_sheep = node.state[0] + state[0]
                left_wolf = node.state[1] + state[1]
                right_sheep = node.state[3] - state[0]
                right_wolf = node.state[4] - state[1]
                next_state = list(node.state)

                if (left_sheep == 0 or (left_sheep > 0 and left_sheep >= left_wolf)) and \
                        (right_sheep == 0 or (right_sheep > 0 and right_sheep >= right_wolf)):
                    next_state[0] = left_sheep
                    next_state[1] = left_wolf
                    next_state[2] = int(node.state[5])
                    next_state[3] = right_sheep
                    next_state[4] = right_wolf
                    next_state[5] = int(not (node.state[5]))

                    child = Node(next_state, node, 'do')
                    # 过滤已探索的点
                    if child.state in _explored:
                        continue
                    print('child node:state:%s ' % (child.state ))
                    # 递归的方法,把当前child返回,并且limit-1
                    result = recursive_dls(child, dst_state, limit - 1)
                    if result == "cutoff":
                        cutoff_occurred = True
                        print('search failure, child state: %s parent state: %s limit cutoff' %
                              (child.state, child.parent.state))
                    elif result != "failure":
                        print('search success')
                        print("At the currnet" ,node.state,"you will take the action",state,"and then,your new state is ",child.state)
                        return result
        if cutoff_occurred:
            return "cutoff"
        else:
            return "failure"


if __name__ == '__main__':
    main()

拓展:输出所有的路径

代码2:

# -*- coding: utf-8 -*-
from collections import deque
# 羊 狼 船 羊 狼 船
initial_state = [3, 3, 1, 0, 0, 0]  # 初始状态
final_state = [0, 0, 0,3, 3, 1]  # 最终状态

action = [[0, -1, 0], [0, -2, 0], [-1, 0, 0], [-2, 0, 0], [-1, -1, 0], [0, 1, 1], [0, 2, 1], [1, 0, 1], [2, 0, 1],
          [1, 1, 1]]

# 利用python的deque队列记录状态转移情况,初始化时加入初始状态。deque是可以从头尾插入和删除的队列,在不指定大小时,为一个无边界的队列
record = deque()
record.append(initial_state)


def next_state_lawful(current_state):

    # 下一个动作判定
    next_action = []
    for state in action:
        #current_state[5] == state[2]是判断右侧的船和action的船,相同就可以用这个action
        #后面的判断狼和羊经过action的操作之后是否是大于0 小于3的
        if current_state[5] == state[2] and (current_state[1] + state[1]) >= 0 and (current_state[1] + state[1]) <= 3 \
                and (current_state[0] + state[0]) >= 0 and (current_state[0] + state[0]) <= 3:
            next_action.append(state)

    # 下一个状态
    for state in next_action:
        left_sheep = current_state[0] + state[0]
        left_wolf = current_state[1] + state[1]
        right_sheep = current_state[3] - state[0]
        right_wolf = current_state[4] - state[1]
        next_state = list(current_state)

        if (left_sheep == 0 or (left_sheep > 0 and left_sheep >= left_wolf)) and \
                (right_sheep == 0 or (right_sheep > 0 and right_sheep >= right_wolf)):
            next_state[0] = left_sheep
            next_state[1] = left_wolf
            next_state[2] = int(current_state[5])
            next_state[3] = right_sheep
            next_state[4] = right_wolf
            next_state[5] = int(not (current_state[5]))
            yield next_state

        # 记录调试的变量:num表示总共实现方法数,record_list记录所有实现路径


num = 0
record_list = []


def searchResult(record,limit):
    if limit==0:
        return
    global num, record_list
    # 由record的末尾元素得到当前状态
    current_state = record[-1]
    # 得到关于当前状态的下一状态的可迭代生成器,供下一步循环使用
    next_state = next_state_lawful(current_state)

    # 遍历所有可能的下一状态
    for state in next_state:
        if state not in record:
            # 保证当前状态没在以前出现过。如果状态已经出现还进行搜索就会形成状态环路,陷入死循环。
            record.append(state)
            # 添加新的状态到列表中
            if state == final_state:
                print(record)
                # 打印出可行方案
                # record_list.append(record)这样使用错误,导致加入列表的是record的引用,应该使用下面的式子来进行深复制,得到一个新的队列再加入列表。
                record_list.append(deque(record))
                num += 1
            else:
                # 递归搜索
                searchResult(record,limit-1)

            # 去除当前循环中添加的状态,进入下一个循环,关键步,第一次实现的时候遗漏了
            record.pop()
searchResult(record,15)
print("总共实现方式的种类数目:", num)
print("实现方式的最少步骤为:%d 步" % (min([len(i) for i in record_list])-1))

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DLS 深度受限搜索 狼羊 过河 问题 python 实现 的相关文章

  • 在Python中不断寻找用户输入

    我将如何编写一个始终寻找用户输入的 Python 程序 我想我希望有一个等于输入的变量 然后根据该变量的等于值会发生不同的情况 因此 如果变量是 w 那么它将执行某个命令并继续执行 直到收到另一个输入 例如 d 然后会发生不同的情况 但直到
  • Pygame 让精灵按照给定的旋转行走

    很久以前我做了一个Scratch脚本 我想用Pygame将其转换为Python 有很多示例显示图像的旋转 但我想知道如何更改精灵的旋转以使其沿给定方向移动 而不更改图像 这是我的暂存代码 这是我的 Pygame 精灵类 class Star
  • 如何在python中确定过去的时区特定日期是否是夏令时?

    有没有办法检查特定时区在我指定的日期是否处于夏令时 test dt datetime year 2015 month 2 day 1 pst pytz timezone America Los Angeles test dt pst loc
  • Seaborn regplot 中点和线的不同颜色

    中列出的所有示例西伯恩的regplot文档 https seaborn pydata org generated seaborn regplot html点和回归线显示相同的颜色 改变color争论改变了两者 如何为点设置与线不同的颜色 你
  • python blpapi安装错误

    我试图根据 README 中的说明为 python 安装 blpapi 3 5 5 但是在运行时 python setup py install 我收到以下错误 running install running build running b
  • 如何使用 python http.server 运行 CGI“hello world”

    我使用的是 Windows 7 和 Python 3 4 3 我想在浏览器中运行这个简单的 helloworld py 文件 print Content Type text html print print print print h2 H
  • 无法使用 Python 循环分页 API 响应

    所以 我对这个感到摸不着头脑 使用 HubSpot 的 API 我需要获取我客户的 门户 帐户 中所有公司的列表 遗憾的是 标准 API 调用一次只能返回 100 家公司 当它返回响应时 它包含两个参数 使分页响应成为可能 其中之一是 ha
  • Scrapy Splash,如何处理onclick?

    我正在尝试抓取以下内容 我能够收到响应 但我不知道如何访问以下项目的内部数据以抓取它 我注意到访问这些项目实际上是由 JavaScript 和分页处理的 这种情况我该怎么办 下面是我的代码 import scrapy from scrapy
  • 在Python中清理属于不同语言的文本

    我有一个文本集合 其中的句子要么完全是英语 印地语或马拉地语 每个句子附加的 id 为 0 1 2 分别代表文本的语言 无论任何语言的文本都可能有 HTML 标签 标点符号等 我可以使用下面的代码清理英语句子 import HTMLPars
  • 为什么在 __init__ 函数中声明描述符类会破坏描述符功能?

    在下面的 B 类中 我想要 set 每当您赋值给 A 类中的函数时 就会调用该函数B a 相反 将值设置为B a覆盖B a与价值 C类分配给C a工作正常 但我想为每个用户类都有一个单独的 A 实例 即我不想在 C 的一个实例中更改 a 来
  • Scapy:如何将新层(802.1q)插入现有数据包?

    我有一个数据包转储 想要将 VLAN 标记 802 1q 标头 注入到数据包中 怎么做 为了找到答案 我查看了Scapy 插入新层和记录问题 https stackoverflow com q 17259592 1381638 这确实很有帮
  • python lxml 使用iterparse编辑并输出xml

    我已经在 lxml 库上摆弄了一段时间了 也许我没有正确理解它 或者我错过了一些东西 但我似乎无法弄清楚在捕获某个 xpath 后如何编辑文件并且然后能够在逐个元素解析时将其写回到 xml 中 假设我们有这个 xml 作为示例
  • telethon 库:如何通过电话号码添加用户

    我正在研究 Telegram 的 Telethon 库 它可以使用 Telegram API 充当 Telegram 客户端 重要提示 这是电报客户端 API https core telegram org telegram api 而不是
  • 使用 os.forkpty() 创建一个伪终端以 ssh 到远程服务器并与其通信

    我正在尝试编写一个 python 脚本 它可以 ssh 到远程服务器 并可以从 python 客户端执行 ls cd 等简单命令 但是 在成功 ssh 到服务器后 我无法读取伪终端的输出 任何人都可以在这里帮助我 以便我可以在服务器上执行一
  • 如何在自定义 django 命令中抽象出命令代码

    我正在我的应用程序下编写自定义 django 命令management commands目录 目前我在该目录中有 6 个不同的文件 每个文件都有不同的命令来解决独特的需求 然而 有一些实用程序是它们所共有的 抽象出这些公共代码的最佳方法是什
  • 列表中的“u”是什么意思?

    这是我第一次遇到这种情况 刚刚打印了一个列表 每个元素似乎都有一个u在它前面 即 u hello u hi u hey 它是什么意思 为什么列表的每个元素前面都会有这个 由于我不知道这种情况有多常见 如果您想了解我是如何遇到它的 我会很乐意
  • 从 python 文件调用 Julia 函数

    我能够创建一个 docker 环境 然后按照这个线程我有一个用 Julia 编写的高性能函数 如何从 Python 中使用它 https stackoverflow com questions 64241264 i have a high
  • python:xml.etree.ElementTree,删除“命名空间”

    我喜欢 ElementTree 解析 xml 的方式 特别是 Xpath 功能 我有一个带有嵌套标签的应用程序的 xml 输出 我想按名称访问此标签而不指定名称空间 这可能吗 例如 root findall molpro job 代替 ro
  • 重写 PyGObject 中的虚拟方法

    我正在尝试实施高宽几何管理 http developer gnome org gtk3 3 2 GtkWidget html geometry management在 GTK 和 Python 中用于我的自定义小部件 我的小部件是来自的子类
  • scikit-learn kmeans 聚类的初始质心

    如果我已经有一个可以作为初始质心的 numpy 数组 我该如何正确初始化 kmeans 算法 我正在使用 scikit learn Kmeans 类 这个帖子 具有选定初始中心的 k 均值 https stackoverflow com q

随机推荐

  • 求最长不含重复字符的子字符串——C++

    声明 本文原题主要来自力扣 记录此博客主要是为自己学习总结 不做任何商业等活动 一 原题描述 剑指 Offer 48 最长不含重复字符的子字符串 请从字符串中找出一个最长的不包含重复字符的子字符串 计算该最长子字符串的长度 示例 1 输入
  • Linux查看进程命令

    查看进程 1 ps 命令用于查看当前正在运行的进程 grep 搜索 例如 ps ef grep java 表示查看所有进程里 CMD 是 java 的进程信息 2 ps aux grep java aux 显示所有状态 ps 3 kill
  • Sublime Text4 配置 Python3 环境、代码提示、编译报错教程

    1 配置 Python3 环境 单击 工具 gt 编译系统 gt 新建编译系统 弹出 替换里面的内容为 cmd G CodeTools anaconda3 python exe u file file regex File line 0 9
  • 数据中台数据分析过程梳理

    在当今社会中 随着企业的快速发展 相关业务系统的建设也会越来越多 新的业务模式 新的IT架构 多云环境的出现等等 而一些问题就逐渐暴露了出来 企业之间的IT无法做到互通 新模式生产数据与旧数据无法互通 企业IT架构错综复杂 底层数据互通更加
  • java使用opencv库二值化图片

    应用场景 截取监控视频图片保存到本地后用作后期监控视频角度调整参考 使用二值化后的图片并进行透明度降低进行监控矫正 package img import java awt Color import java awt image Buffer
  • delphi XE5如何把其它程序而不是本软件在通知区域的图标隐藏?不是关闭进程。请举个详细例子,比如Shell_NotifyIcon...

    Delphi XE5可以使用API函数Shell NotifyIcon来实现隐藏其它程序的图标 具体代码例子如下 procedure HideIcon APid Cardinal var noteIconData TNOTIFYICONDA
  • 关于 hostapd

    关于 hostapd 主页 http w1 fi hostapd hostapd是一个IEEE 802 11的AP和IEEE 802 1X WPA WPA2 EAP RADIUS验证器 此页面用于怎么在linux系统下使用它 其他操作系统请
  • 金融贷款行业实时高精准获客 ——三网运营商大数据

    都说生产是第一因素 但对于任何企业来说 客户来源才是第一因素 在大多数行业 获得客户的困难已经成为行业的挑战 如今 许多行业和企业获得客户的主要来源是在线促销和客户获取 现在几乎每个人都有一部手机 运营商可以根据移动客户的访问行为 通信行为
  • 排查java.net.MalformedURLException: Local host name unknown: java.net.UnknownHostException:***

    首先排查 vi etc sysconfig network 没有就加上 HOSTNAME 你的主机名 XXXX 如果有 接着排查 vi etc hosts 没有就加上 127 0 0 1 localhost localdomain loca
  • 2021年全球与中国高速分散机行业市场规模及发展前景分析

    2021年全球与中国高速分散机行业市场规模及发展前景分析 本报告研究全球与中国市场高速分散机的发展现状及未来发展趋势 分别从生产和消费的角度分析高速分散机的主要生产地区 主要消费地区以及主要的生产商 重点分析全球与中国市场的主要厂商产品特点
  • 论文阅读:DeepFake-Adapter: Dual-Level Adapter for DeepFake Detection(Deepfake模型快速调参)

    一 论文信息 论文名称 DeepFake Adapter Dual Level Adapter for DeepFake Detection 作者团队 项目主页 https github com rshaojimmy DeepFake Ad
  • python爬取 百姓网部分数据 + 存入MongoDB数据库详细案例

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 目录 前言 一 实施步骤 二 目标网站 先分析目标网站 三 获取数据 1 引入库 2 请求数据 2 1 获取第一层链接 3 抓取数据 3 1 分析页面 3 2 抓取数据 四
  • 图像可变游程之混乱代码

    图像可变游程之混乱代码 图像可变游程之混乱编码 可变游程编码 VLC 混乱编码 参考代码 图像可变游程之混乱编码 这里 对我的自画像代码作一个简要解释 自画像代码实际上是一个解码器 包括两个部分 图像的可变游程编码 varied lengt
  • ValueError: check_hostname requires server_hostnameWARNING: You are using pip version 21.1.3

    ValueError check hostname requires server hostname WARNING You are using pip version 21 1 3 however version 22 2 2 is av
  • LCD1602芯片的使用——简单易懂

    题目 想在LCD1602上显示两行如下字样 huaianxinxi wantin 想完成上面的显示必须掌握LCD1602芯片的基本知识 将在程序下面附上LCD1602芯片的基本知识 供大家参考 我实现的比较简单 没有什么花哨的显示 大家首先
  • js 聚合函数

    在JavaScript中 聚合函数是一种用于处理数据集合的函数 它们接收一个数据集合作为输入 并返回一个单一的值作为输出 聚合函数通常用于对数据进行统计 计算总和 平均值 最大值 最小值等操作 下面是一些常见的聚合函数的概念 sum 求和
  • Vscode搭建轻量级Matlab开发环境

    一 使用Vscode编写m文件的优势与不足 Matlab的启动速度很慢 为追求效率与编写体验 对于一些简单的m文件编写 我们可以选择在Vscode中进行编写和运行 Vscode插件丰富 配置好Matlab环境后 可以实现以下功能 代码高亮
  • MATLAB及Simulink----基本知识简介

    目前 MATLAB已成为国际上最为流行的科学计算与工程计算软件工具之一 如今的MATLAB已经不仅仅是矩阵运算或数值计算的软件 它已经发展成为一种具有广泛应用前景 全新的计算机高级编程语言 可以说它是 第四代 计算机语言 自20世纪90年代
  • Sqli-labs之Less-37

    Less 37 POST型 绕过 MYSQL real escape string 本关与 34 关是大致相似的 区别在于处理 post 内容用的是 mysql real escape string 函数 而不是 addslashes 函数
  • DLS 深度受限搜索 狼羊 过河 问题 python 实现

    深度受限搜索 DLS 简单地说就是深度有限搜索 DFS 深度限制 limit DLS伪代码 实例 狼羊 过河 问题 3只羊和3头狼在河岸A 想要过河抵达河岸B 它们只有一艘船并且船上必须有1 2只生物 当 任意一边的狼的数量大于羊时 羊会被