java实现迷宫算法--转
沿着所有方向进行探测,有路径则走,没有路径则从栈中回退。
回溯法是一种不断试探且及时纠正错误的搜索方法,下面的求解过程采用回溯法。从入口出发,按某一方向向前探索,若能走通(未走过的),即某处可以到达,则到达一个新点,否则试探下一个方向;若所有的方向均没有通路,则沿原路返回前一点,换下一个方向继续试探,直到所有可能的通路都搜索到,或找到一条通路,或无路可走又返回到入口点。这里可以用一个栈来实现,每走一步,将该位置压入栈中,若该点无路可走,则出栈返回上一位置。
需要解决的四个问题:
(1)表示迷宫的数据结构
设迷宫为m行n列,利用数组maze[m][n]来表示一个迷宫,maze[i][j]=0或1,其中0表示通路,1表示不通。迷宫该数组四边都为1,代表迷宫四周都是墙。这样就可以保证每个点都有8个方向可以试探。
入口为(1,1),出口为(6,8)
1,1,1,1,1,1,1,1,1,1
1,0,1,1,1,0,1,1,1,1
1,1,0,1,0,1,1,1,1,1
1,0,1,0,0,0,0,0,1,1
1,0,1,1,1,0,1,1,1,1
1,1,0,0,1,1,0,0,0,1
1,0,1,1,0,0,1,1,0,1
1,1,1,1,1,1,1,1,1,1
(2)试探方向
迷宫中间每个点都有8个方向可以试探。其增量数组可以用一个8*2的二维数组move表述,表示对当前点而言,它周围8个点的行和列的坐标偏移量.具体值如下:
x y
0 1
1 1
1 0
1 -1
0 -1
-1 -1
-1 0
-1 1
在move数组中,x表示横坐标的增量,y表示纵坐标的增量。
(3)栈中存放元素的设计
栈中所存放的元素应该包含所到达的每点的坐标以及从该点沿哪个方向向下走的,可用一个类表示:
class Step{
int x,y,d;
public Step(int x,int y,int d) {
this.x = x;//横坐标
this.y = y;//纵坐标
this.d = d;//方向
}
}
(4)防止重复到达某点而发生死循环
使maze[i][j]置为-1,以便区别为达到的点,同样也可以防止走重复点的作用。
源码如下:
package com.test; import java.util.Stack;
class Step{
int x,y,d;
public Step(int x,int y,int d) {
this.x = x;//横坐标
this.y = y;//纵坐标
this.d = d;//方向
}
} public class MazeTest { public static void main(String[] args) {
// 迷宫定义
int[][] maze = {{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,}};
int[][] move = {{,},{,},{,},{,-},{,-},{-,-},{-,},{-,}};
Stack s = new Stack();
Stack s1 = new Stack();
int a = path(maze, move, s);
while(!s.isEmpty()){
Step step = s.pop();
System.out.println(step.x+":"+step.y);
}
}
public static int path(int[][] maze,int[][] move,Stack s){
Step temp = new Step(,,-); //起点
s.push(temp);
while(!s.isEmpty()){
temp = s.pop();
int x = temp.x;
int y = temp.y;
int d = temp.d+;
while(d<){
int i = x + move[d][];
int j = y + move[d][];
if(maze[i][j] == ){ //该点可达
temp = new Step(i,j,d); //到达新点
s.push(temp);
x = i;
y = j;
maze[x][y] = -; //到达新点,标志已经到达
if(x == && y == ){
return ; //到达出口,迷宫有路,返回1
}else{
d = ; //重新初始化方向
}
}else{
d++; //改变方向
}
}
}
return ;
} }
代码2:
import java.util.*;
class Position{
public Position(){
}
public Position(int row, int col){
this.col = col;
this.row = row;
}
public String toString(){
return "(" + row + " ," + col + ")";
}
int row;
int col;
}
class Maze{
public Maze(){
maze = new int[][];
stack = new Stack<Position>();
p = new boolean[][];
}
/*
* 构造迷宫
*/
public void init(){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入迷宫的行数");
row = scanner.nextInt();
System.out.println("请输入迷宫的列数");
col = scanner.nextInt();
System.out.println("请输入" + row + "行" + col + "列的迷宫");
int temp = ;
for(int i = ; i < row; ++i) {
for(int j = ; j < col; ++j) {
temp = scanner.nextInt();
maze[i][j] = temp;
p[i][j] = false;
}
}
}
/*
* 回溯迷宫,查看是否有出路
*/
public void findPath(){
// 给原始迷宫的周围家一圈围墙
int temp[][] = new int[row + ][col + ];
for(int i = ; i < row + ; ++i) {
for(int j = ; j < col + ; ++j) {
temp[][j] = ;
temp[row + ][j] = ;
temp[i][] = temp[i][col + ] = ;
}
}
// 将原始迷宫复制到新的迷宫中
for(int i = ; i < row; ++i) {
for(int j = ; j < col; ++j) {
temp[i + ][j + ] = maze[i][j];
}
}
// 从左上角开始按照顺时针开始查询
int i = ;
int j = ;
p[i][j] = true;
stack.push(new Position(i, j));
while (!stack.empty() && (!(i == (row) && (j == col)))) {
if ((temp[i][j + ] == ) && (p[i][j + ] == false)) {
p[i][j + ] = true;
stack.push(new Position(i, j + ));
j++;
} else if ((temp[i + ][j] == ) && (p[i + ][j] == false)) {
p[i + ][j] = true;
stack.push(new Position(i + , j));
i++;
} else if ((temp[i][j - ] == ) && (p[i][j - ] == false)) {
p[i][j - ] = true;
stack.push(new Position(i, j - ));
j--;
} else if ((temp[i - ][j] == ) && (p[i - ][j] == false)) {
p[i - ][j] = true;
stack.push(new Position(i - , j));
i--;
} else {
stack.pop();
if(stack.empty()){
break;
}
i = stack.peek().row;
j = stack.peek().col;
}
}
Stack<Position> newPos = new Stack<Position>();
if (stack.empty()) {
System.out.println("没有路径");
} else {
System.out.println("有路径");
System.out.println("路径如下:");
while (!stack.empty()) {
Position pos = new Position();
pos = stack.pop();
newPos.push(pos);
}
}
/*
* 图形化输出路径
* */
String resault[][]=new String[row+][col+];
for(int k=;k<row;++k){
for(int t=;t<col;++t){
resault[k][t]=(maze[k][t])+"";
}
}
while (!newPos.empty()) {
Position p1=newPos.pop();
resault[p1.row-][p1.col-]="#";
}
for(int k=;k<row;++k){
for(int t=;t<col;++t){
System.out.print(resault[k][t]+"\t");
}
System.out.println();
}
}
int maze[][];
private int row = ;
private int col = ;
Stack<Position> stack;
boolean p[][] = null;
}
class hello{
public static void main(String[] args){
Maze demo = new Maze();
demo.init();
demo.findPath();
}
}
java实现迷宫算法--转的更多相关文章
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- Java面试常见算法题
1.实现字符串反转 提供七种方案实现字符串反转 import java.util.Stack; public class StringReverse { public static String re ...
- 故障重现(内存篇2),JAVA内存不足导致频繁回收和swap引起的性能问题
背景起因: 记起以前的另一次也是关于内存的调优分享下 有个系统平时运行非常稳定运行(没经历过大并发考验),然而在一次活动后,人数并发一上来后,系统开始卡. 我按经验开始调优,在每个关键步骤的加入如 ...
- Elasticsearch之java的基本操作一
摘要 接触ElasticSearch已经有一段了.在这期间,遇到很多问题,但在最后自己的不断探索下解决了这些问题.看到网上或多或少的都有一些介绍ElasticSearch相关知识的文档,但个人觉得 ...
- 论:开发者信仰之“天下IT是一家“(Java .NET篇)
比尔盖茨公认的IT界领军人物,打造了辉煌一时的PC时代. 2008年,史蒂夫鲍尔默接替了盖茨的工作,成为微软公司的总裁. 2013年他与微软做了最后的道别. 2013年以后,我才真正看到了微软的变化. ...
- 故障重现, JAVA进程内存不够时突然挂掉模拟
背景,服务器上的一个JAVA服务进程突然挂掉,查看产生了崩溃日志,如下: # Set larger code cache with -XX:ReservedCodeCacheSize= # This ...
- 死磕内存篇 --- JAVA进程和linux内存间的大小关系
运行个JAVA 用sleep去hold住 package org.hjb.test; public class TestOnly { public static void main(String[] ...
- 【小程序分享篇 一 】开发了个JAVA小程序, 用于清除内存卡或者U盘里的垃圾文件非常有用
有一种场景, 手机内存卡空间被用光了,但又不知道哪个文件占用了太大,一个个文件夹去找又太麻烦,所以我开发了个小程序把手机所有文件(包括路径下所有层次子文件夹下的文件)进行一个排序,这样你就可以找出哪个 ...
- Java多线程基础学习(二)
9. 线程安全/共享变量——同步 当多个线程用到同一个变量时,在修改值时存在同时修改的可能性,而此时该变量只能被赋值一次.这就会导致出现“线程安全”问题,这个被多个线程共用的变量称之为“共享变量”. ...
随机推荐
- 有趣的库:pipe(类似linux | 管道)库
pipe并不是Python内置的库,如果你安装了easy_install,直接可以安装它,否则你需要自己下载它:http://pypi.python.org/pypi/pipe 之所以要介绍这个库,是 ...
- 分布式文件系统--GFS
分布式文件系统 分布式文件系统:当数据集的大小超过一台独立物理计算机的存储能力时,就有必要对它进行分区(partition)并存储到若干台单独的计算机上.管理网络中夸多台计算机存储的文件系统.这种系统 ...
- poj 3299 Humidex
直接套公式就可以,可我套公式第一遍都错了,英语差的孩子伤不起(┬_┬) #include <iostream> #include <cmath> #include <io ...
- asp.net mvc 4 编译错误 CS0012
CS0012: The type 'System.Data.Objects.DataClasses.EntityObject' is defined in an assembly that is no ...
- [转]软件开发过程(CMMI/RUP/XP/MSF)是与非?
经常看到和听到大家在争论敏捷过程.RUP和CMM 哪个软件开发过程更好或者哪个过程不好,各自都有理由.争论得不亦乐乎......实际上,没有十全十美的过程,也不存在更好的过程.关键是什么样的过程适合自 ...
- OC三种方法实现定时器
在软件开发过程中,我们常常需要在某个时间后执行某个方法,或者是按照某个周期一直执行某个方法.在这个时候,我们就需要用到定时器. 在iOS中有很多方法完成定时器的任务,例如 NSTimer.CADisp ...
- 使用Office-Word的博客发布功能(测试博文)
本人打算在博客园开博,但平时收集和整理资料都在OneNote中,又不想在写博客时还要进行复制粘贴操作,于是就想到了Microsoft Office自带的博客发布功能.在此做了一下测试,发布了此博文. ...
- [转]在Arcmap中加载互联网地图资源的4种方法
转自http://blog.3snews.net/space.php?uid=6955280&do=blog&id=67981 前一段时间想在Arcmap中打开互联网地图中的地图数据, ...
- chrome内核浏览器缓存资源找回方法
曾几何时,用chrome浏览器看了某个图片,网页,视频等,当时没保存,后来再怎么找都找不到了,chrome还把缓存加密了,不能像ie那样找回,这世上有买后悔药的吗?还真有! 搜索chromeCache ...
- wikioi 3038 3n+1问题
题目描述 Description 3n+1问题是一个简单有趣而又没有解决的数学问题.这个问题是由L. Collatz在1937年提出的.克拉兹问题(Collatz problem)也被叫做hailst ...