首页 > 编程语言 >用A*算法设计搜索策略,补全关于下列走迷宫问题的程序

用A*算法设计搜索策略,补全关于下列走迷宫问题的程序

时间:2024-03-15 15:03:36浏览次数:45  
标签:补全 state self 迷宫 solution 算法 table def row

 补全下列关于走迷宫的程序:

class Node():
    #TODO: 完成结点类的定义,结点中要包含状态、父结点、算符等必要成员。根据算法需求,还可能包含该结点的路径代价、启发函数值、估计代价等信息
    def __init__(self, state, parent, action, stepCost, hCost):
        self.state = state                          #结点状态
        self.parent = parent                        #父节点
        self.action = action                        #父结点至当前结点算符
        if parent != None:
            self.cost = parent.cost + stepCost
        else:
            self.cost = 0
        self.hCost = hCost
        self.estCost = self.cost + hCost

class Open():
    #构造函数
    def __init__(self):
        self.table = []

    #增加新结点
    def add(self, node):
        self.table.append(node)
        self.table.sort(key=lambda x:x.estCost, reverse=True)

    #表中是否已有该状态结点
    def contains_state(self, state):
        for node in self.table:
            if node.state == state:
                return True    
        return False

    #判断Open表是否空
    def empty(self):
        return len(self.table) == 0

    #从Open表中移出结点
    def remove(self):
        if self.empty():
            raise Exception("无解")             #无解异常
        else:
            if self.empty():
                raise Exception("无解")
            else:
                node = self.table[-1]
                self.table = self.table[:-1]
            return node

class ClosedTable():
    #构造函数
    def __init__(self):
        self.table = []

    #添加结点
    def add(self, node):
        self.table.append(node)

    #表中是否已有该状态结点
    def contains_state(self, state):
        for node in self.table:
            if node.state == state:
                return True
        return False
class Maze():
    #构造函数
    def __init__(self, filename):

        # 读取迷宫文件,并设置迷宫范围
        with open(filename) as f:
            contents = f.read()

        # 确定迷宫有效性
        if contents.count("A") != 1:
            raise Exception("迷宫需要有唯一的起点")
        if contents.count("B") != 1:
            raise Exception("迷宫需要有唯一终点")

        # 确定迷宫长宽范围
        contents = contents.splitlines()
        self.height = len(contents)
        self.width = max(len(line) for line in contents)

        # 找出迷宫墙壁
        self.walls = []
        for i in range(self.height):
            row = []
            for j in range(self.width):
                try:
                    if contents[i][j] == "A":
                        self.start = (i, j)
                        row.append(False)
                    elif contents[i][j] == "B":
                        self.goal = (i, j)
                        row.append(False)
                    elif contents[i][j] == " ":
                        row.append(False)
                    else:
                        row.append(True)
                except IndexError:
                    row.append(False)
            self.walls.append(row)

        self.solution = None
#打印输出迷宫
    def print(self):
        solution = self.solution[1] if self.solution is not None else None
        print()
        for i, row in enumerate(self.walls):
            for j, col in enumerate(row):
                if col:
                    print("█", end="")
                elif (i, j) == self.start:
                    print("A", end="")
                elif (i, j) == self.goal:
                    print("B", end="")
                elif solution is not None and (i, j) in solution:
                    print("*", end="")
                else:
                    print(" ", end="")
            print()
        print()

    
    def output_image(self, filename, show_solution=True, show_explored=False):
        from PIL import Image, ImageDraw

        cell_size = 50
        cell_border = 2

        # 创建画布
        img = Image.new(
            "RGBA",
            (self.width * cell_size, self.height * cell_size),
            "black"
        )
        draw = ImageDraw.Draw(img)

        solution = self.solution[1] if self.solution is not None else None
        for i, row in enumerate(self.walls):
            for j, col in enumerate(row):

                # 墙
                if col:
                    fill = (40, 40, 40)

                # 起点
                elif (i, j) == self.start:
                    fill = (255, 0, 0)

                # 终点
                elif (i, j) == self.goal:
                    fill = (0, 171, 28)

                # 解法
                elif solution is not None and show_solution and (i, j) in solution:
                    fill = (220, 235, 113)

                # 已探索点
                elif solution is not None and show_explored and  closed_table.contains_state((i, j)):
                    fill = (212, 97, 85)

                # 空格子
                else:
                    fill = (237, 240, 252)

                # 绘制格子
                draw.rectangle(
                    ([(j * cell_size + cell_border, i * cell_size + cell_border),
                      ((j + 1) * cell_size - cell_border, (i + 1) * cell_size - cell_border)]),
                    fill=fill
                )

img.save(filename)
        infer_img = '/home/aistudio/'+filename
        print(infer_img)
        img = Image.open(infer_img)
        display(img)


    def actions(self, state):
        row, col = state
        candidates = [
            ("上", (row - 1, col)),
            ("下", (row + 1, col)),
            ("左", (row, col - 1)),
            ("右", (row, col + 1))
        ]

        result = []
        for action, (r, c) in candidates:
            if 0 <= r < self.height and 0 <= c < self.width and not self.walls[r][c]:
                result.append((action, (r, c)))
        return result

    def heuristic(self, state):
        (i, j) = self.goal
        (x, y) = state
        #TODO: 设计启发函数计算h值,替换下面语句
        h = 0
        for y in range(len(state)):
            for x in range(len(state[y])):
                if state[y][x] != self.goalState[y][x]:
                    for i in range(len(state)):
                        for j in range(len(state[y])):
                            if state[y][x] == self.goalState[i][j]:
                                if state[y][x] != 0:
                                    h += abs(y-i) + abs(x-j)
        return h

class Solver(Maze):
    #结点扩展
    def expand(self, node):
        actions = self.actions(node.state)
        result = []
        for action, (r, c) in actions:
            childState = (r, c)
            childHCost = self.heuristic(childState)
            child = Node(state=childState, parent=node, action=action, stepCost=1, hCost=childHCost)                                 #TODO:依照结点类定义,补全()中代码,生成扩展结点
            result.append(child)
        return result


    def solve(self):
        #初始设定
        startHCost = self.heuristic(self.start)
        start = Node()                                     #TODO:依照结点类定义,补全()中代码,生成初始状态结点
        open_table = Open()                                                 #实例化Open表                                                
        open_table.add(start)                                               #将初始状态结点填至Open表   
        closed_table = ClosedTable()

        # 循环求解
        while True:
            #Open表为空,则所有结点均探索完,还没找到目标状态结点,无解异常
            if open_table.empty():
                raise Exception("无解")

            #从Open表中取出结点
            node = open_table.remove()

            #目标验证
            if node.state == self.goal:
                actions = []                        #求解路径
                cells = []
                while node.parent is not None:      #由目标状态结点逆推至初始状态结点
                    actions.append(node.action)     #将逆推路径结点添加至求解路径
                    cells.append(node.state)
                    node = node.parent
                actions.reverse()                   #将逆推求解路径翻转至正序
                cells.reverse()
                self.solution = (actions, cells)
                num = len(closed_table.table)+len(open_table.table)
                return  num, closed_table

            #TODO:完成代码,将从Open表中取出待扩展结点添加至Closed表(已探索结点)


            #扩展结点,获得后继结点
            children = self.expand(node)

            #如果扩展的后继结点既不在Open表中,也不在Closed表中,则添加至Open表
            for child in children:
                if not open_table.contains_state(child.state) and not closed_table.contains_state(child.state):
                    open_table.add(child)


# 程序运行

filename = '/home/aistudio/maze2.txt'               #载入迷宫文件

m = Solver(filename)                                #求解问题
print("迷宫:")
m.print()
print("求解中...")
num, closed_table = m.solve()
print("共探索:", num, "个点")
print("解法:")
m.print()
m.output_image("maze.png", show_explored=True)      #输出图形

标签:补全,state,self,迷宫,solution,算法,table,def,row
From: https://blog.csdn.net/bhxlm/article/details/136739680

相关文章

  • 代码随想录算法训练营第四十七天| ● 198.打家劫舍 ● 213.打家劫舍II ● 337.打家
    打家劫舍 题目链接:198.打家劫舍-力扣(LeetCode)思路:每一家的最大收益来源只有两个,一个是这家不偷,那么最大收益等于从上一家出来的最大收益,另一个是偷这一个家,因此最大收益等于从上上一家出来的最大收益加这一家的收益。classSolution{public:introb(vector<int>&nu......
  • 代码随想录算法训练营第四十七天 | 337.打家劫舍III,213.打家劫舍II ,198.打家劫舍
     198.打家劫舍 已解答中等 相关标签相关企业 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一......
  • Light Random Sprays Retinex 传统的图像增强算法LRSR
    文章目录前言1、LightRandomSpraysRetinex概况2、LightRandomSpraysRetinex具体实现2.1、噪声去除2.2、亮度调整2.3、插值技术3、LightRandomSpraysRetinex源码4、LightRandomSpraysRetinex效果及结论前言  LightRandomSpraysRetinex,即“光随......
  • 基于python+django的协同过滤算法的小说推荐系统
    摘 要随着世界经济信息化、全球网络化的到来推动信息线上管理的飞速发展,为小说推荐的管理起到关件作用。若想达到安全,快捷的目的,就需要拥有信息化的组织和管理模式,建立一套合理、畅通、高效的小说推荐系统,通过此网站爬虫技术获取数据。当前的银行用户行为管理存在工作效率......
  • 聚类算法-K-means
    主要在K-means的理解1介绍K-means算法,以及具体的过程K-means算法是常用的聚类算法之一,属于无监督学习,主要用来将标签未知的数据划分成较少的类/簇,类内的样本差异要小,类间的样本差异要大,这可以帮助我们探索数据结构和分布。K-means的具体实现过程:(四步)初始化模型参数:聚类的簇......
  • 人工智能时代,Java从业者必学科目:数据机构和算法,以及AI算法和技能
    【晋升攻略】Java开发者的AI时代高薪加速器在AI时代,Java从业者必学的科目包括数据结构与算法、AI算法和相关技能,这是因为这些知识和技能是构建和发展人工智能应用的基础。具体分析如下:1.数据结构与算法:数据结构和算法是计算机科学的核心,对于编写高效、可维护的代码至关重......
  • 代码随想录算法训练营第七天|LeetCode 344.反转字符串、541.反转字符串II、卡码网54.替
    344.反转字符串题目描述:​编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组s的形式给出。不要给另外的数组分配额外的空间,你必须**原地修改输入数组**、使用O(1)的额外空间解决这一问题。示例一:输入:s=["h","e","l","l","o"]输出:["o","l","l......
  • 代码随想录算法训练营第十天| 232. 用栈实现队列 225. 用队列实现栈
    232.用栈实现队列https://leetcode.cn/problems/implement-queue-using-stacks/description/classMyQueue{Stack<Integer>stackIn;Stack<Integer>stackOut;publicMyQueue(){stackIn=newStack<>();stackOut=new......
  • 贪心算法(算法竞赛、蓝桥杯)--均分纸牌
    1、B站视频链接:A30贪心算法P1031[NOIP2002提高组]均分纸牌_哔哩哔哩_bilibili题目链接:[NOIP2002提高组]均分纸牌-洛谷#include<bits/stdc++.h>usingnamespacestd;intn,a[101],av,cnt;intmain(){ scanf("%d",&n); for(inti=1;i<=n;i++){ scanf("%d&quo......
  • 贪心算法(算法竞赛、蓝桥杯)--奶牛晒衣服
    1、B站视频链接:A28贪心算法P1843奶牛晒衣服_哔哩哔哩_bilibili题目链接:奶牛晒衣服-洛谷#include<bits/stdc++.h>usingnamespacestd;priority_queue<int>q;//用大根堆维护湿度的最大值intn,a,b;inttim,maxn;intmain(){ scanf("%d%d%d",&n,&a,&b); for......