数据结构与算法笔记:农夫过河问题python3实现

探讨了农夫带狼、羊和菜过河的经典问题,通过Python算法实现了寻找安全过河路径的方法,确保在无人看管时,狼不会吃羊,羊不会吃菜。
部署运行你感兴趣的模型镜像

问题描述

农夫(Human)过河。一个农夫带着一只狼(Wolf),一只羊(Sheep)和一些菜(Vegetable)过河。河边只有一条船,由于船太小,只能装下农夫和他的一样东西。在无人看管的情况下,狼要吃羊,羊要吃菜,请问农夫如何才能使三样东西平安过河?

要求:
输出一行,为最终的过河方式,方案格式为 过河人员、回来人员、过河人员、回来人员、…、过河人员。
过去和回来的人员之间,用空格隔开。
以四个生物英文的首字母代指对应的生物(H->Human,W->Wolf,S->Sheep,V->Vegetable)

最终输出示例:HS H HW H

算法实现

使用python举例

#!/usr/bin/env python3

# H->Human,W->Wolf,S->Sheep,V->Vegetable
name = ["H", "W", "S", "V"]
search_finish = False; # 用于判定 递归截止

# 完成状态的判断
def is_done(status):
    return status[0] and status[1] and status[2] and status[3]

# 生成下一个局面的所有情况
def generate_next_status(status):
    next_status_list = []

    for i in range(0, 4):
        if status[0] != status[i]: # 和农夫不在一侧?
            continue

        next_status = [status[0],status[1],status[2],status[3]]
        # 农夫和其中一个过河,i 为 0 时候,农夫自己过河。
        next_status[0] = not next_status[0] # 农夫自身取反
        next_status[i] = next_status[0] # 和农夫一起过河
        # 如果是安全的状态, 那么将本次状态加入状态列表
        if is_valid_status(next_status):
            next_status_list.append(next_status)

    return next_status_list

# 判断是否合法的局面 安全局面
def is_valid_status(status):
    if status[1] == status[2]:
        if status[0] != status[1]:
            # 狼和羊同侧,没有人在场 不安全
            return False

    if status[2] == status[3]:
        if status[0] != status[2]:
            # 羊和草同侧,没有人在场 不安全
            return False
    return True

# 搜索程序
def do_search(history_status):
    global search_finish

    if search_finish:
        return

    current_status = history_status[len(history_status) - 1] # 获取当前状态

    next_status_list = generate_next_status(current_status) # 生成下一次状态
    for next_status in next_status_list:
        # 去重处理
        if next_status in history_status:
            continue
            
        history_status.append(next_status) # 加入下一个状态
        # 完成后输出
        if is_done(next_status):
            search_finish = True
            print(get_solution(history_status))
        else:
            do_search(history_status) # 未完成则继续搜索

        history_status.pop()

#根据前后状态输出过河指标 过去的状态和现在的状态对比
def output_cross(pre, now):
    res = [] # 用于存放当前数据
    for i in range(len(pre)):
        if pre[i] != now[i]:
            res.append(name[i])
    return ''.join(res)

#打印过程 根据历史栈 转换成 过河标识
def get_solution(history_status):
    result = ''
    hs_len = len(history_status)
    for i in range(hs_len):
        # output_cross
        # 从第二个开始 比较
        if i > 0:
            result += output_cross(history_status[i-1], history_status[i])
            # 不是最后一个
            if i != hs_len - 1:
                result += ' '
    return result

if __name__ == "__main__":
    # 初始化第一次状态
    status = [False, False, False, False]
    # 初始化历史状态
    history_status = [status]
    # 触发搜索
    do_search(history_status)

最终输出:
HS H HW HS HV H HS

您可能感兴趣的与本文相关的镜像

Python3.11

Python3.11

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值