美文网首页
人狼羊草问题

人狼羊草问题

作者: EBcoco | 来源:发表于2019-03-30 12:52 被阅读0次

    1.题目:

    一农夫带着一头狼,一只羊和一担草过河,小船只能一次装载农夫和一样货物,狼会吃羊,羊会吃草,只有农夫在时才安全。现欲让所有物品包括农夫都安全过道河对岸,使用程序实现求解。

    2.设计思路:

    使用布尔列表来设置人狼羊草的状态, false代表不过河,true 代表渡河
    那么人狼羊草的初始状态就是 status = [ false , false , false , false ]
    最后状态应该是 status = [ true , true , true , true ]

    渡河规则:

    1.每次渡河农夫的状态都必须改变
    2.每次渡河, 狼 羊 草的状态最多改变一位
    3.狼 羊 草 存在食物链克制情况下必须有农夫存在

    根据规则以初始状态为根节点,生成后续状态,再做枚举,生成状态树
    如果子节点出现与根节点相同的状态,则不再生成子树

    编码流程:

    1,创建状态历史列表
    2.生成所有方案
    3.遍历判断所生成方案,判断是否是最终状态,是则输出
    4.不是则判断改状态是否存在于状态历史列表
    5.是则回到 3 ,继续遍历,不是则存入状态历史列表,回到 2 继续执行
    (ps.算法流程图就不画了,凑活看,有人画可以发给我)

    代码:

    status = [False, False, False, False]
              # 人    狼     羊     草
    

    判断状态是否合规

    def judge_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 create_all_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 judge_status(next_status):
                next_status_list.append(next_status)
    
        return next_status_list
    

    树形递归遍历

    def search(history_status):
        global scheme_count
        current_status = history_status[len(history_status) - 1]
    
        next_status_list = create_all_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):
                scheme_count += 1
                print("scheme " + str(scheme_count) + ":")
                print_history_status(history_status)
            else:
                search(history_status)
    
            history_status.pop()
    # 这里是找到满足方案后,将其弹出历史状态列表,继续查找下一个方案
    

    判断是否达到最终状态,都过河,则返回Ture

    def well_done(status):
        return status[0] and status[1] and status[2] and status[3]
    

    最后可以写个方法处理一下列表,打印出过程

    求其他思路,最好能不用遍历树

    相关文章

      网友评论

          本文标题:人狼羊草问题

          本文链接:https://www.haomeiwen.com/subject/vvyjbqtx.html