zoukankan      html  css  js  c++  java
  • day21 Go 实现的深度优先搜索实现迷宫算法

    # Go 实现的深度优先搜索实现迷宫算法

    package main
    
    import (
    	"errors"
    	"fmt"
    	"os"
    )
    
    // 读取文件中的数据,使用循环生成迷宫图
    func readMazeFile(filename string) [][]int {
    	file, err := os.Open(filename)
    	defer file.Close()
    
    	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
    }
    
    type point struct {
    	i, j int
    }
    
    // 反转slice
    func reverse(lst []point) []point {
    	newList := []point{}
    	for index, _ := range lst {
    		n := len(lst) - index - 1
    		newList = append(newList, lst[n])
    	}
    	return newList
    }
    
    func isExist(lst []point, n point) error {
    	for _, ex := range lst {
    		if ex == n {
    			return errors.New(" is exist!")
    		}
    	}
    	return nil
    }
    
    // 移动步骤顺序: 上、左、下、右
    var direction = [4]point{
    	{-1, 0}, {0, -1}, {1, 0}, {0, 1}}
    
    // 执行上左下右移动操作
    func (p point) move(r point) point {
    	return point{p.i + r.i, p.j + r.j}
    }
    
    // 判断移动之后的位置是否有越界或者撞墙
    func (p point) at(grid [][]int) (int, error) {
    	if p.i < 0 || p.i >= len(grid) {
    		return 0, errors.New("raw out of range")
    	}
    
    	if p.j < 0 || p.j >= len(grid[0]) {
    		return 0, errors.New("col out of range")
    	}
    
    	return grid[p.i][p.j], nil
    }
    
    func walk(maze [][]int, start, end point) []point {
    
    	Q := []point{start}
    	history := []point{start}
    	search_path := []point{}
    
    	for {
    		// 此处的flag用于判断当前的坐标的下几个步骤是否都是死路,如果有一个出口就标记为true,后面需要判断死路使用
    		flag := false
    
    		now := Q[len(Q)-1]
    		search_path = append(search_path, now)
    
    		// 找到出口
    		if now == end {
    			break
    		}
    
    		for _, d := range direction {
    			next := now.move(d)
    
    			// 判断下个点在前面没有探测过, 避免重复探测
    			if isExist(history, next) == nil {
    				// 判断移动没有越界,而且没有撞墙的话将下个点加入到队列中
    				val, err := next.at(maze)
    				if err == nil && val != 1 {
    					Q = append(Q, next)
    					history = append(history, next)
    					//fmt.Printf("now:%d, moveTo:%d, next:%d 
    ", now, d, next)
    					flag = true
    					continue
    				}
    
    			} else {
    				//fmt.Println("3--> history is exist ", next)
    			}
    		}
    
    		// 判断当前坐标移动的下一步都是是死路的时候删除队列中最后一个元素
    		if flag == false && isExist(history, now) != nil {
    			//fmt.Println("dead way", now)
    			Q = Q[:len(Q)-1]
    			search_path = search_path[:len(search_path)-1]
    		}
    
    	}
    
    	return search_path
    }
    
    func main() {
    
    	maze := readMazeFile("/Users/fanghongbo/CloudStation/go/goDemo/src/chapter09/maze.txt")
    /* maze.txt的内容如下:
    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
    */
    	fmt.Printf("maze: 
    
    ")
    	for i := range maze {
    		for j := range maze[i] {
    			fmt.Printf("%3d", maze[i][j])
    		}
    		fmt.Println()
    	}
    	fmt.Println()
    
    	path := walk(maze, point{0, 0}, point{len(maze) - 1, len(maze[0]) - 1})
    	fmt.Printf("最终路径为:%d
    ",path)
    }
    

      

  • 相关阅读:
    MySQL 5.6 Reference Manual-14.1 Introduction to InnoDB
    CSS3 Media Queries 详细介绍与使用方法
    jQuery圆形统计图实战开发
    PHP+Mysql+jQuery实现中国地图区域数据统计(raphael.js)
    Javascript实战开发:教你使用raphael.js绘制中国地图
    WEB开发中常用的正则表达式集合
    互联网技术开发者必备的调试工具和脚本
    CSS3实战开发: 纯CSS实现图片过滤分类显示特效
    CSS3实战开发:使用CSS3实现photoshop的过滤效果
    :link,:visited,:focus,:hover,:active详解
  • 原文地址:https://www.cnblogs.com/fanghongbo/p/9995585.html
Copyright © 2011-2022 走看看