深度优先和广度优先

import numpy as np
#迷宫中0的位置代表墙,不能走
#8代表入口,1代表可走位置
#https://blog.csdn.net/weixin_42147487/article/details/80268390
#88代表出口
migong = '''
0	0	0	0	0	0	0	0	0	0
0	8	1	0	1	1	1	0	0	0
0	1	1	0	1	1	1	0	1	0
0	1	1	1	1	0	0	1	1	0
0	1	0	0	0	1	1	1	1	0
0	1	1	1	0	1	0	1	1	0
0	1	0	1	1	1	0	1	1	0
0	1	0	0	0	1	0	1	1	0
0	0	1	1	1	1	1	1	888	0
0	0	0	0	0	0	0	0	0	0'''
data = np.array(migong.split(), dtype = int).reshape((10,10))     #已经转化为数组类型
 
 
def direction_set(data):
    """
        函数功能,找到data中未被走过的地方,并同时记录该地方能够走的地方
    """
    dir_set = {}
    v, h = np.where(data > 0)   #https://www.cnblogs.com/massquantity/p/8908859.html   #元组形式,为横纵坐标
    for i,j in zip(v, h):
        key = str(i) + str(j)
        if data[i, j+1] > 0:            #该地方东邻块是否能走
            dir_set[key] = [(i, j+1)]
        if data[i+1, j] > 0:            #该地方南邻块是否能走
            if key in dir_set:
                dir_set[key] += [(i+1, j)]
            else:
                dir_set[key] = [(i+1, j)]
        #data[i, j-1]
        if data[i, j-1] > 0:            #该地方西邻块是否能走
            if key in dir_set:
                dir_set[key] += [(i, j-1)]
            else:
                dir_set[key] = [(i, j-1)]
        #data[i-1, j]
        if data[i-1, j] > 0:            #该地方北邻块是否能走
            if key in dir_set:
                dir_set[key] += [(i-1, j)]
            else:
                dir_set[key] = [(i-1, j)]
    return dir_set
 
step = []       #记录走的状态
key_old = '11'  #起始位置
print(data, '\n')
 
while True:
    #print(data)
    direct_set = direction_set(data)
    if key_old == '88':  #当到达出口的位置,就不用继续往别处走
        print(data)
        print([i for i,j in step])
        break
    if key_old in direct_set:
        step += [(key_old, direct_set[key_old])]   #关键字+原来关键字中可走的
        data[int(key_old[0]), int(key_old[1])] = -8
        coors = direct_set[key_old][0]   #找到当前位置第一个可以走的节点,也类似于方向
        key_old = str(coors[0]) + str(coors[1])   #更新kold
    else:
        for i in range(len(step)):
            huish = step.pop()
            key = huish[0]
            values = huish[1]
            if len(values) == 1:
                data[int(key[0]), int(key[1])] = 1
                #print(data)
            else:
                key_old = str(values[1][0]) + str(values[1][1])
                step += [(key, values[1:])]
                #print(data)
                break

参考

class Maze(object):
 
    def __init__(self, maze, start, end):
 
        self.maze = maze
        self.start = start
        self.end = end
        self.direction = [[-1, 0], [0, -1], [1, 0], [0, 1]]  # 移动方向顺序: 上左下右
 
    def move(self, x, y):
        """
        执行迷宫的上下左右操作
        :param x: 起始坐标
        :param y: 移动的方向
        :return: 新的坐标
        """
 
        return [x[0] + y[0], x[1] + y[1]]
 
    def at(self, grid, x):
        """
        传入一个maze和坐标,判断坐标是否越界,如果没有越界根据坐标返回对应maze中的数值
        :param grid: maze
        :param x: 查找坐标
        :return: maze中的数值和状态
        """
        # 判断row 是否越界
        if x[0] < 0 or x[0] >= len(grid):
            return 0, False
        # 判断col 是否越界
        if x[1] < 0 or x[1] >= len(grid[0]):
            return 0, False
 
        return grid[x[0]][x[1]], True
 
    def walk(self):
        """
        创建一个新的二维数组,self.maze每走一步,就在这个新的二维数组对应位置上记录行走的步数
        :return: 记录了行走步数的二维数组
        """
        # 创建一个大小和self.maze一样大小的二维数组,此二维数组中所有的值初始化为0,用来记录行走的步数
        steps = [[i * 0 for i in range(len(self.maze[0]))] for j in range(len(self.maze))]
 
        Q = [self.start]
 
        while len(Q) > 0:
            index = Q[0]
            # 找到出口
            if index == self.end:
                break
 
            Q = Q[1:]
 
            for d in self.direction:
                next = self.move(index, d)
 
                val, ok = self.at(self.maze, next)
 
                # 越界或者撞墙,跳过
                if not ok or val == 1:
                    continue
 
                # 新的二维数组中移动的下一个点如果值不是0的话,说明已经走过这个点,直接跳过
                val, ok = self.at(steps, next)
                if not ok or val != 0:
                    continue
 
                # 回到原点
                if next == self.start:
                    continue
 
                # 将steps中每走一步,记录当前的步数
                val, ok = self.at(steps, index)
                if ok:
                    steps[next[0]][next[1]] = val + 1
 
                # 每走一步,将此时的位置加入到队列中
                Q.append(next)
 
        return steps
 
    def path(self, grid):
        """
        根据steps计算最优路径
        :param grid: steps迷宫图
        :return: 存放路径的列表
        """
        last = grid[len(maze) - 1][len(maze[0]) - 1]
        lookup_path = [[len(maze) - 1, len(maze[0]) - 1], ]
 
        while last > 0:
            last -= 1
            index = lookup_path[-1]
 
            for d in self.direction:
                next = self.move(index, d)
 
                val, err = self.at(grid, next)
                if val == last:
                    lookup_path.append(next)
                    break
 
        return lookup_path
 
 
if __name__ == '__main__':
 
    #maze = [[0, 0, 1, 0, 1], [1, 0, 0, 0, 1], [0, 0, 1, 1, 0], [0, 1, 0, 0, 0], [0, 0, 0, 1, 0]]
    maze = [[0, 1, 0, 0, 0], [0, 0, 0, 1, 0], [0, 1, 0, 1, 0], [1, 1, 1, 0, 0], [1, 0, 1, 1, 0], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0]]
 
    # 打印二维数组
    print("原始迷宫图:")
    for k in maze:
        for v in k:
            print("%2d" % v, end=" ")
        print("")
 
    print("\n")
 
    print("行走路线图:")
    step = Maze(maze, [1, 0], [len(maze) - 2, len(maze[0]) - 1])
    steps = step.walk()
 
    for k in steps:
        for v in k:
            print("%2d" % v, end=" ")
        print("")
 
    print("\n")
 
    print("走出迷宫共需要%s步\n" % steps[len(maze) - 2][len(maze[0]) - 1])
 
    # 计算最优路径
    path = step.path(steps)
    path.reverse()
    print("最优路径是: ", path)
#https://www.cnblogs.com/fanghongbo/p/9995602.html


lookup_path = []
history_path = []
# maze = [[0, 0, 1, 0, 1], [1, 0, 0, 0, 1], [0, 0, 1, 1, 0], [0, 1, 0, 0, 0], [0, 0, 0, 1, 0]]
maze = [[0, 1, 0, 0, 0], [0, 0, 0, 1, 0], [0, 1, 0, 1, 0], [1, 1, 1, 0, 0], [0, 1, 0, 0, 1], [0, 1, 0, 0, 0]]
 
# 打印二维数组
for k in maze:
    for v in k:
        print(v, end=" ")
    print("")
 
print("\n")
 
 
def up(location):
    # 到达了数组顶端
    if location[0] == 0:
        return False
    else:
        new_location = [location[0] - 1, location[1]]
 
        # 走过的路不再走
        if new_location in history_path:
            return False
        # 遇到墙不走
        elif maze[new_location[0]][new_location[1]] == 1:
            return False
        else:
            lookup_path.append(new_location)
            history_path.append(new_location)
            return True
 
 
def down(location):
    # 遇到迷宫最下方的时候,不能继续往下走
    if location[0] == len(maze) - 1:  # 6行5列的二维数组行数,从0开始计算所以是6-1=5 行
        return False
    else:
        new_location = [location[0] + 1, location[1]]
        # 走过的路不再走
        if new_location in history_path:
            return False
        # 遇到墙不走
        elif maze[new_location[0]][new_location[1]] == 1:
            return False
        else:
            history_path.append(new_location)
            lookup_path.append(new_location)
            return True
 
 
def left(location):
    # 遇到迷宫最左边,不能继续往左走
    if location[1] == 0:
        return False
    else:
        new_location = [location[0], location[1] - 1]
        # 走过的路不再走
        if new_location in history_path:
            return False
        # 遇到墙不走
        elif maze[new_location[0]][new_location[1]] == 1:
            return False
        else:
            history_path.append(new_location)
            lookup_path.append(new_location)
            return True
 
 
def right(location):
    # 遇到迷宫最右边,不能继续向右移动
    if location[1] == len(maze[0]) - 1:  # 6行5列的二维数组列数,从0开始计算所以是5-1=4行
        return False
    else:
        new_location = [location[0], location[1] + 1]
        # 走过的路不再走
        if new_location in history_path:
            return False
        # 遇到墙不走
        elif maze[new_location[0]][new_location[1]] == 1:
            return False
        else:
            history_path.append(new_location)
            lookup_path.append(new_location)
            return True
 
 
start = [0, 0]
end = [5, 4]
print("start: %s --> end: %s\n" % (start, end))
lookup_path.append(start)
history_path.append(start)
 
while lookup_path[-1] != end:
    now = lookup_path[-1]
    # print("retry:%s, Lookup path:%s" % (now, route_stack))
    if up(now) or down(now) or left(now) or right(now):
        continue
 
    lookup_path.pop()
 
print("final path: ", lookup_path)

参考2深度优先

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值