Go语言 - 广度优先算法(走迷宫)

2021年9月19日 21点热度 0条评论 来源: 信er

前言:最近在慕课网看了个视屏学习广度优先算法,通过这个算法来计算出走出迷宫的最短路径,因此在此记录来加深自己对广度优先算法的理解。

目录

 

一、什么是广度优先算法?广度优先算法能做什么?

二、代码实现

三、最终结果

一、什么是广度优先算法?广度优先算法能做什么?

广度优先算法(Breadth-First Search),同广度优先搜索,又称作宽度优先搜索,或横向优先搜索,简称BFS,是一种图形搜索演算法。

 

我们会经常碰到这样一个问题,从一个起点A开始要到一个终点B,我们要找寻一条最短的路径。这个时候广度优先算法就用上了,为此,我们可以得到2个问题。

问题一:起点A是否有路径到达终点B?

问题二:起点A到达起点B的最短路径是什么?

通过上面的个问题我们来实现我在视屏里学习的用这个算法来走出迷宫(我也是照着视屏敲的.........)

 

二、代码实现

假设下图是一个迷宫总共6行5列,数字1是一堵墙,数字0表示是可以走的路,那么我们将计算出从起点A到终点B的最短距离及路线,路线我已经画出来了,下面我直接贴实现代码了。。

 

1.实现代码

package main

import (
	"fmt"
	"os"
)

func main() {
	maze := readMaze("maze/maze.in") //读取迷宫文件

	//传入迷宫地图,起点坐标[0,0]终点坐标[]
	data := walk(maze, point{0, 0}, point{len(maze) - 1, len(maze) - 1})

	for _, row := range data {
		for _, val := range row {
			fmt.Printf("%3d", val)
		}
		fmt.Println()
	}
}

/**
*作用:坐标结构体
*修改:无
 */
type point struct {
	i, j int
}

/**
*作用:下一个节点的坐标
*修改:无
 */
func (p point) add(r point) point {
	return point{p.i + r.i, p.j + r.j}
}

/**
*作用:当前坐标的值,验证是否越界及路是否可走
*修改:无
 */
func (p point) at(grid [][]int) (int, bool) {
	//验证X轴是否越界
	if p.i < 0 || p.i >= len(grid) {
		return 0, false
	}

	//验证Y轴是否越界
	if p.j < 0 || p.j >= len(grid[p.i]) {
		return 0, false
	}

	return grid[p.i][p.j], true
}

/**
*作用:当前坐标对应的周围坐标,上下左右
*修改:无
 */
var dirs = [4]point{
	{0, 1}, {-1, 0}, {0, -1}, {1, 0},
}

/**
*作用:实现
*修改:无
 */
func walk(maze [][]int, start, end point) [][]int {
	//初始化来记录等下要走的路
	steps := make([][]int, len(maze))
	for i := range steps {
		steps[i] = make([]int, len(maze[i]))
	}

	//需要走的路,起始第一步,【0,0】
	q := []point{start}

	//开始走
	for len(q) > 0 {
		cur := q[0] //获得起点的坐标(当前坐标)
		q = q[1:]   //删除当前的位置(当前坐标)

		for _, dir := range dirs {
			next := cur.add(dir) //下一个位置的坐标,因为有4个

			//是否越界
			val, ok := next.at(maze)
			if !ok || val == 1 {
				continue
			}

			//是否走过
			val, ok = next.at(steps)
			if !ok || val != 0 {
				continue
			}

			//回到起点
			if next == start {
				continue
			}

			curSteps, _ := cur.at(steps)
			steps[next.i][next.j] = curSteps + 1

			q = append(q, next)

		}

	}
	return steps
}

/**
作用:读取文件里的数据
*/
func readMaze(filename string) [][]int {
	file, err := os.Open(filename)
	if err != nil {
		panic(err)
	}

	var row, col int
	fmt.Fscanf(file, "%d %d", &row, &col)

	maze := make([][]int, row)
	for i := range maze {
		maze[i] = make([]int, col)
		for j := range maze[i] {
			fmt.Fscanf(file, "%d", &maze[i][j])
		}
	}

	return maze
}

2.迷宫文件信息

6 5
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

3.。。。。

 

三、最终结果

下图即为最终结果,我们可以看出从A到B路径和最短路径是13步

 

备注:写的不好,如果发现有错或者有疑问欢迎各位评论指正,如果您有好的方法或技巧欢迎交流讨论

备注:可以不用买下面学习来源连接里的课程,399浪费钱,百度搜下会有很多网盘资源

学习来源https://coding.imooc.com/class/180.html

 

 

 

 

 

 

 

 

 

 

    原文作者:信er
    原文地址: https://blog.csdn.net/qq_40876727/article/details/84337941
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。