算法6.分支限界法下的迷宫游戏
来源:互联网 发布:加拿大数据分析专业 编辑:程序博客网 时间:2024/04/29 20:39
以一个m×n的0-1矩形阵表示迷宫,其中0和1分别表示迷宫中的通路和障碍。请用分支限界法设计一个算法,对任意设定的m×n迷宫,求出一条从入口到出口的通路,或得出没有通路的结论;如果有通道,请输出具有最短路径的通道。一个输入实例如下图所示:
/
(1) 算法设计思路
先定义指标如果向右移动,则row=0,col=1,如果先左移动,则row=-1,col=0,先上移动则,row=0,col=-1,先下移动则,row=0,col=1;然后对当前的位置进行上下左右的搜索,如果搜索到对应位置的数值为0时,对应位置的数值=当前位置的数值+1,一直循环下去直到当前位置的row和col=目标位置的row和col。然后利用循环回溯,依次标记可以移动的相邻位置,再判断该位置是否可以移动,不可以移动时判断是否到终点,是否无解,如果都不是就取下一个节点,如果是可以移动的位置,则根据上下左右的标记进行判断,为0则将该位置是数值赋值为上一个位置的值+1
(2) 算法实现的伪代码及其计算时间复杂度分析
求解迷宫老鼠游戏的算法Find(Position start,Position end)
输入:起始位置的坐标,终点位置的坐标
输出:如果有解,则输出最短可行路径,无解则输出-1
s1: 初始化相对位移,posit[] offset=new positon[4]s2: 右初始化为position(0,1)s3: 下初始化为position(1,0)s4: 左初始化为position(0,-1)s5: 上初始化为position(-1,0)s6: 初始化起始位置的坐标 position here=new position(start.row,start.col)s7: 初始化起始位置的距离为2,x[start.row][start.col]=2s8: 创建一个队列q存放positions9: position nbr=new position(0,0)s10: do {标记可达相邻位置s11: for (inti =0 to 3)s12: begin nbr.col=here.cor+offset[i].col;s13: nbr.row=here.row+offset[i].row;s14: if (当前的行,列不越界并且要到达的位置为0)s15: begin x[nbr.row][nbr.col] = x[here.row][here.col] + 1s16: if (当前行,列到终点行,列) break;s17: else q.add(new position(nbr.row,nbr.col));s18: end if s19: end fors20: if (当前行,列到终点行,列) break;s21: if 队列为空,返回-1,无解s22: else 取下一个扩展结点here=(position)q.remove();s23: }while (true)s24: 构造最短迷宫路径s25: pathlen=x[start.row][start.col]-2;s26: path=new position[pathlen];s27: here=new position(end.row,end.col)s28: for (inti =pathlen-1 to 0){s29: begin path[i]=new position(here.row,here.col)s30: for (int j=0 to 3){s31: begin nbr.row=here.row+offset[i].row;s32: nbr.col=here.col+offset[i].col;s33: if当前的行,列不越界并且要到达的位置为2 s34: break;s35: end for s36: end fo;s37: here=new position(nbr.row,nbr.col)
算法fucntionA的计算时间复杂度分析:O(mn)
(3) 实验代码及运行结果
import java.util.LinkedList; import java.util.Queue; public class 迷宫游戏 { private static int[][] x = { { 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 1, 0, 1, 0, 0 }, { 0, 0, 0, 1, 0, 1, 0, 0, 0, 0 }, { 0, 1, 0, 1, 0, 1, 0, 1, 1, 0 }, { 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 }, { 0, 1, 1, 1, 0, 1, 0, 1, 0, 1 }, { 0, 1, 0, 0, 0, 1, 0, 1, 0, 1 }, { 0, 1, 0, 1, 1, 1, 0, 1, 0, 0 }, { 1, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0 } }; private static int pathlen = 0; // 最短线路长度 private static position path[] = null; public static int findPath(position start, position end) { // 初始化相对位移 position[] offset = new position[4]; offset[0] = new position(0, 1);// right offset[1] = new position(1, 0);// down offset[2] = new position(0, -1);// left offset[3] = new position(-1, 0);// up position here = new position(start.row, start.col); x[start.row][start.col] = 2; // 起始位置的距离 int numOfNbrs = 4; // 标记可达位置 Queue<position> q = new LinkedList<position>(); position nbr = new position(0, 0); do {// 标记可达相邻方格 for (int i = 0; i < numOfNbrs; i++) { nbr.col = here.col + offset[i].col; nbr.row = here.row + offset[i].row; if (nbr.row >= 0 && nbr.col >= 0 && (nbr.row <= 9 && nbr.col <= 9) && x[nbr.row][nbr.col] == 0) {// 读方格未标记 // System.out.print(nbr.row + " "); // System.out.print(nbr.col + " "); x[nbr.row][nbr.col] = x[here.row][here.col] + 1; // System.out.println(x[nbr.row][nbr.col]); if ((nbr.row == end.row) && (nbr.col == end.col)) { break;// 完成 } else { q.add(new position(nbr.row, nbr.col)); // 这里要将新创建的结点放进去,而不能直接q.add(nbr),因为这样是将q中的 // 对象引用和nbr指向同一个对象,后续如果改变nbr,将会影响到q中的对象。 } } } if ((nbr.row == end.row) && (nbr.col == end.col)) break; // 完成 if (q.isEmpty()) return -1; // 无解 else { here = (position) q.remove(); // 取下一个扩展结点 } } while (true); //构造最短迷宫路径 pathlen = x[end.row][end.col] - 2; //System.out.println(pathlen); path = new position[pathlen]; //从目标位置end开始向前回溯 here = new position(end.row, end.col); for (int i = pathlen - 1; i >= 0; i--) { path[i] = new position(here.row, here.col); //找前驱位置 for (int j = 0; j < 4; j++) { nbr.row = here.row + offset[j].row; nbr.col = here.col + offset[j].col; if (nbr.row >= 0 && nbr.col >= 0 && (nbr.row <= 9 && nbr.col <= 9) && x[nbr.row][nbr.col] == i + 2) { break; } } here = new position(nbr.row, nbr.col);//先、前移动 } return x[end.row][end.col] - 2; } public static void main(String[] args) { position start = new position(0, 0); position finish = new position(9, 9); findPath(start, finish); System.out.println("最短路劲为:入口(1,1)->"); for (int i = 0; i < 36; i++){ if (i%6==5) System.out.println("("+(path[i].row+1) + "," + (path[i].col+1)+")"+"->"); else System.out.print("("+(path[i].row+1) + "," + (path[i].col+1)+")"+"->"); } } } class position { public int col, row; public position(int r, int c) { this.col = c; this.row = r; } }
0 0
- 算法6.分支限界法下的迷宫游戏
- 算法-分支限界法
- 算法-分支限界法
- 分支限界批处理的算法
- 算法(6):分支限界法
- 分支限界法五大常用算法之五:分支限界法
- 分支限界算法的多线程实现
- 装载问题的分支限界算法实现
- Lintcode 关于分支限界算法的总结
- 分支限界法-最少步数走出迷宫
- 常用算法五(分支限界法)
- 常用算法五(分支限界法)
- 常用算法五(分支限界法)
- 常用算法之分支限界法
- 常用算法五(分支限界法)
- 算法入门7:分支限界法
- 常用算法五(分支限界法)
- 回溯法与分支限界算法
- Linux磁盘分析
- 通用嵌入式操作系统开发(1)
- Linearian Colony
- Facebook面试题 Suffix array sorting
- Docker 入门基础
- 算法6.分支限界法下的迷宫游戏
- 排序算法汇总
- 疯狂复习
- STM32基础知识
- 微信小程序_厕所雷达
- Hive面试题考点-整理
- Luabit的位运作简介
- Cloud9 ide使用phpmyadmin
- 如何获取iphone基带芯片工作时候获取到的一些参数呢,如信号强度,小区,周围小区以及一些更深入的参数,有人了解吗