AI传教士和野人渡河问题-实验报告

简介: AI传教士和野人渡河问题-实验报告

一 题目要求:


      设有m个传教士和n个野人来到河边,打算乘一只船从左岸渡到右岸去,该船每次最多载3人。在任何时候,如果野人人数超过传教士人数,那么野人就会把传教士吃掉。他们怎样才能用这条船安全地把所有人都渡河过去?试采用宽带优先和深度优先方法分析搜索过程。(说明:传教士和野人都会划船,测试:m=n=3)

二 构造状态空间:


这个题目的状态空间秒数为一组整数对(a,b,flag)。

a是左边岸上剩下的传教士数

b是左边岸上剩下的野人数目

flag取值为1时,船在左岸;flag取值为0是,船在右岸。

所以,初始状态为(m,n,1),目的状态为(0,0,0)。

三 对题目的理解:


  可以想象到,这个题目应该采用树形结构来解,所以如何建立每个节点的数据结构就是难点。这里用Python写的算法,结点的数据结构如下:

class Point:
    def __init__(self, a, b, flag):
        self.a = a  # 左岸传教士数量
        self.b = b  # 左岸野人数量
        self.flag = flag  # flag = 1: 船在左岸;flag = 0: 船在右岸
        self.father = None
        self.node = [a, b, flag]

      比较重要的是Point结点的father属性,指明了子节点与父节点的关系,保证了树形结构的准确性。

四 代码解释:


首先定义了传教士数目、野人数目、open表、closed表,声明了Point类,定义了初始节点init(3,3,3)和目的节点(0,0,0)。

在开始进行BFS算法或者DFS算法之前,先定义几个函数:

1) safe:判断该节点内在左岸、右岸、船舶上的传教士数目是否大于野人数目或者有一方为0;

2) equal:判断两个节点是否相同。这里防止组合“爆炸”(老师上课说的)或者说是死循环。这里是为了检测OPEN表和CLOSED表写的函数;

3) back:判断该节点是否是父节点,防止节点重复;

4) in_list:判断这个节点是否在某个表中。用来判断新生成的节点是否在OPEN表或者CLOSE表中。

开始编写BFS算法和DFS算法:

1) 首先,先把初始节点init放入到OPEN表中,然后遍历OPEN表;

2) 如果OPEN中取出的节点是目的节点goal,那么结束遍历;否则把这个节点从OPEN表取出,放入CLOUSED表;

3) 然后根据此节点,来得到它的子节点,它的子节点要满足几个规则:符合题目规定的安全问题;不是父节点;不在OPEN表中;不在CLOUSED表中;

4) 如果3的条件满足,那么把这个新节点放入OPEN表。深度优先和广度优先的区别在于,深度优先把新节点放在OPEN表的OPEN[0]位置,而广度优先把新节点放在OPEN表的末尾(这也是老师上课强调的)。

最后打印一下路径,就可显示出解。

五 算法输出分析:


1、 BFS宽度优先算法 结果分析

   如图1,是BFS算法打印出OPEN表的部分截图(太多了,就不全粘贴了),然后根据OPEN表可以写出宽度优先的遍历路径如图2。

image.png

图1-BFS算法结果

image.png

图2-BFS算法结果分析

2、 DFS宽度优先算法 结果分析

      如图3,是DFS算法打印出OPEN表的部分截图(太多了,就不全粘贴了),然后根据OPEN表可以写出深度优先的遍历路径如图4。

image.png

图3-DFS算法结果

image.png

图4-DFS算法结果分析

六 代码:


A = 3  # 传教士数量
B = 3  # 野人数量
K = 3  # 最大乘坐人数量
OPEN = []  # open表
CLOSED = []  # closed表
class Point:
    def __init__(self, a, b, flag):
        self.a = a  # 左岸传教士数量
        self.b = b  # 左岸野人数量
        self.flag = flag  # flag = 1: 船在左岸;flag = 0: 船在右岸
        self.father = None
        self.node = [a, b, flag]
init = Point(A, B, 1)  # 初始节点
goal = Point(0, 0, 0)  # 目标节点
# 判断传教士是否安全
def safe(s):
    if s.a > A or s.a < 0 or s.b > B or s.b < 0 or (s.a != 0 and s.a < s.b) or (s.a != A and A - s.a < B - s.b):
        return False
    else:
        return True
def equal(a, b):
    if a.node == b.node:
        return True
# 判断当前状态与父状态是否一致
def back(new, s):
    if s.father is None:
        return False
    return equal(new, s.father)
# 扩展节点时在open表和closed表中找原来是否存在相同mcb属性的节点
def in_list(new, l):
    for item in l:
        if new.node == item.node:
            return True
    return False
def BFS(s):
    global OPEN, CLOSED
    OPEN = [s]
    CLOSED = []
    while OPEN:  # open表非空
        get = OPEN[0]  # 取出open表第一个元素get
        if get.node == goal.node:  # 判断是否为目标节点
            return get
        OPEN.remove(get)  # 将get从open表移出
        CLOSED.append(get)  # 将get加入closed表
        # 以下得到一个get的新子节点new并考虑是否放入open
        for i in range(A):  # 上船传教士
            for j in range(B):  # 上船野人
                # 船上非法情况
                if i + j == 0 or i + j > K or (i != 0 and i < j):
                    continue
                if get.flag == 1:  # 当前船在左岸,下一状态统计船在右岸的情况
                    new = Point(get.a - i, get.b - j, 0)
                else:  # 当前船在右岸,下一状态统计船在左岸的情况
                    new = Point(get.a + i, get.b + j, 1)
                if not safe(new) or back(new, get):  # 状态非法或new折返了
                    pass
                # 如果要拓展的节点满足以上情况,将它的父亲设为当前节点,计算f,并对open_list排序
                else:
                    new.father = get
                    if in_list(new, OPEN):
                        pass
                    elif in_list(new, CLOSED):
                        pass
                    else:
                        OPEN.append(new)
        print('OPEN表:')
        for o in OPEN:
            print(o.node)
def DFS(s):
    global OPEN, CLOSED
    OPEN = [s]
    CLOSED = []
    while OPEN:  # open表非空
        get = OPEN[0]  # 取出open表第一个元素get
        if get.node == goal.node:  # 判断是否为目标节点
            return get
        OPEN.remove(get)  # 将get从open表移出
        CLOSED.append(get)  # 将get加入closed表
        # 以下得到一个get的新子节点new并考虑是否放入open
        for i in range(A):  # 上船传教士
            for j in range(B):  # 上船野人
                # 船上非法情况
                if i + j == 0 or i + j > K or (i != 0 and i < j):
                    continue
                if get.flag == 1:  # 当前船在左岸,下一状态统计船在右岸的情况
                    new = Point(get.a - i, get.b - j, 0)
                else:  # 当前船在右岸,下一状态统计船在左岸的情况
                    new = Point(get.a + i, get.b + j, 1)
                if not safe(new) or back(new, get):  # 状态非法或new折返了
                    pass # CHILD.pop()
                # 如果要拓展的节点满足以上情况,将它的父亲设为当前节点,计算f,并对open_list排序
                else:
                    new.father = get
                    if in_list(new, OPEN):
                        pass
                    elif in_list(new, CLOSED):
                        pass
                    else:
                        OPEN.insert(0,new)
        print('OPEN表:')
        for o in OPEN:
            print(o.node)
# 递归打印路径
def printPath(f):
    if f is None:
        return
    printPath(f.father)
    # 注意print()语句放在递归调用前和递归调用后的区别。放在后实现了倒叙输出
    print(f.node)
if __name__ == '__main__':
    final = DFS(init)
    if final:
        print('有解,解为:')
        printPath(final)
    else:
        print('无解!')


相关文章
|
人工智能 Devops
AI 应用 DevOps 新体验--实验小结
AI 应用 DevOps 新体验--实验小结
273 0
|
11月前
|
存储 人工智能 云计算
挑战杯专属支持资源|阿里云-AI大模型算力及实验资源丨云工开物
阿里云发起的“云工开物”高校支持计划,助力AI时代人才培养与科研创新。为“挑战杯”参赛选手提供专属算力资源、AI模型平台及学习训练资源,包括300元免费算力券、百炼大模型服务、PAI-ArtLab设计平台等,帮助学生快速掌握AI技能并构建优秀作品,推动产学研融合发展。访问链接领取资源:https://university.aliyun.com/action/tiaozhanbei。
|
JSON 分布式计算 数据处理
加速数据处理与AI开发的利器:阿里云MaxFrame实验评测
随着数据量的爆炸式增长,传统数据分析方法逐渐显现出局限性。Python作为数据科学领域的主流语言,因其简洁易用和丰富的库支持备受青睐。阿里云推出的MaxFrame是一个专为Python开发者设计的分布式计算框架,旨在充分利用MaxCompute的强大能力,提供高效、灵活且易于使用的工具,应对大规模数据处理需求。MaxFrame不仅继承了Pandas等流行数据处理库的友好接口,还通过集成先进的分布式计算技术,显著提升了数据处理的速度和效率。
|
10月前
|
人工智能 文字识别 供应链
高校实验实训课程开发:基于现有的硬件基础和开源能力研发最前沿的AI实验课程
更多基于学校现有硬件基础:企业需求场景的开发和发展,更加注重上层数据和应用,各类工具软件的出现,极大提升了各类硬件的应用价值。我们看到各类硬件厂商,想方设法把硬件卖给学校,但是很多硬件不是在那里尘封,就是寥寥无几的使用场景,我们希望基于学校现有的硬件基础去开发更多面向不同行业或专业的实验实训课程,物尽其用。基于学校现有的硬件,集约开发,极大降低硬件投入成本。
430 7
|
机器学习/深度学习 存储 人工智能
预定下一个诺奖级AI?谷歌量子纠错AlphaQubit登Nature,10万次模拟实验创新里程碑
谷歌的量子纠错算法AlphaQubit近日登上《自然》杂志,被誉为量子计算纠错领域的重大突破。量子比特易受环境噪声干扰,导致计算错误,而AlphaQubit通过神经网络学习噪声模式,显著提升纠错准确性。实验结果显示,它在Sycamore处理器和Pauli+模拟器上表现优异,优于现有解码算法。尽管面临资源需求高等挑战,AlphaQubit为实用化量子计算带来新希望,并可能推动其他领域创新。论文详见:https://www.nature.com/articles/s41586-024-08148-8
386 5
|
人工智能 运维 Serverless
低成本 Serverless AI 检索介绍和实验
本文介绍了低成本Serverless AI检索技术,分为四部分:1) AI检索介绍,通过电商客服案例展示AI检索的应用和优势;2) 表格存储介绍,详细解释了表格存储的结构化数据处理能力及其在AI检索中的作用;3) 实验:RAG,通过具体实验演示基于表格存储的RAG流程及效果;4) 总结,强调向量检索、易用性和丰富的接口特性。整体内容展示了如何利用Serverless架构实现高效、低成本的AI检索解决方案。
376 9
|
机器学习/深度学习 人工智能 自然语言处理
具身AI的实验:一个团队的Alexa Prize夺冠历程
具身AI的实验:一个团队的Alexa Prize夺冠历程
277 1
具身AI的实验:一个团队的Alexa Prize夺冠历程
|
人工智能 安全 决策智能
OpenAI推出实验性“Swarm”框架,引发关于AI驱动自动化的争论
OpenAI推出实验性“Swarm”框架,引发关于AI驱动自动化的争论
394 14
|
人工智能
用AI人模拟社会学实验,居然成功了?斯坦福、NYU用GPT-4模仿人类,准确度惊人!
斯坦福大学和纽约大学的研究团队利用GPT-4模型成功模拟了人类在社交互动中的行为模式,实验结果显示AI能以惊人准确度模仿人类对话,甚至在在线论坛和社交媒体上与真人难以区分。这一突破不仅展示了AI在社会学研究中的巨大潜力,还引发了对AI伦理和透明度的深入探讨。尽管存在一些局限性和挑战,这项研究为未来社会学实验提供了新工具和方法。[论文地址:https://docsend.com/view/qeeccuggec56k9hd]
761 2
|
tengine 人工智能 算法
极智AI | 量化实验分享四:Data-Free Quantization香不香?详解高通DFQ量化算法实现
大家好,我是极智视界,本文剖析一下高通 DFQ (Data-Free Quantization) 量化算法实现,以 Tengine 的实现为例。
1464 1

热门文章

最新文章