今天遇到一个问题,我同学做的一个迷宫课程设计,在随机生成的一个迷宫地图里面查找最优的路径的问题,很多的时候我们会觉得查找最优路径用Dijkstra算法或者Foley算法拿到,但是他的数据太多了,我很难转成图,把哪一个路的点设计为一个图的节点,这样显得更加的复杂化这个程序的算法。
我的办法就是,用Dijkstra算法得解决问题办法+广度优先遍历的算法思想+两个队列,
迷宫的数据如下:
boolean[][] brick= {
{true, false, false, false,false,false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,false, false, false,false},
{true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,true, true, true,true},
{false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,false, false, false,true},
{false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,false, false, false,true},
{false, true, false, false, false, false, false, false, false, false, true, true, true, true, false, false, false, false, false, false, false,false, false, false,true},
{false, true, true, false, false, true, true, true, true, true, true, false, false, true, false, false, false, false, false, false, false,false, false, false,true},
{false, false, true, false, false, true, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false,false, false, false,true},
{false, false, true, false, false, true, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false,false, false, false,true},
{false, false, true, true, false, true, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false,false, false, false,true},
{false, false, false, true, false, true, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false,false, false, false,true},
{false, false, false, true, false, true, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, true, true, true, true},
{false, false, false, true, false, true, true, true, false, false, false, false, false, false, true, false, false, false, false, false, false,true, false, true,true},
{false, false, false, true, true, false, false, true, false, false, false, false, false, false, true, false, false, false, false, true, true, true, false, true,true},
{false, false, false, false, true, false, false, true, false, false, false, false, false, false, true, false, true, true, true, true, false, false, false, true,true},
{false, false, false, false, true, false, false, true, false, false, false, false, true, true, true, false, true, false, false, false, false,false, false, true,true},
{false, false, false, false, true, false, false, true, false, false, false, false, true, false, false, false, true, false, false, false, false,false, false, true,true},
{false, false, false, false, true, true, true, true, false, false, false, false, true, false, false, false, true, false, false, false, false,false, false, false,true},
{false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, false, false, false, false,false, false, false,true},
{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,false, false, false,true},
{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,false, false, false,true},
};
可能会有点粗暴,见面我就不做展示,true代表的是路,false代表的是墙
先看代码把:
import java.util.ArrayDeque;
import java.util.Queue;
/**
* shaoyayu
*/
public class WalkMaze {
public static void main(String[] args) {
boolean[][] brick= {
{true, false, false, false,false,false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,false, false, false,false},
{true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,true, true, true,true},
{false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,false, false, false,true},
{false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,false, false, false,true},
{false, true, false, false, false, false, false, false, false, false, true, true, true, true, false, false, false, false, false, false, false,false, false, false,true},
{false, true, true, false, false, true, true, true, true, true, true, false, false, true, false, false, false, false, false, false, false,false, false, false,true},
{false, false, true, false, false, true, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false,false, false, false,true},
{false, false, true, false, false, true, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false,false, false, false,true},
{false, false, true, true, false, true, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false,false, false, false,true},
{false, false, false, true, false, true, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false,false, false, false,true},
{false, false, false, true, false, true, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, true, true, true, true},
{false, false, false, true, false, true, true, true, false, false, false, false, false, false, true, false, false, false, false, false, false,true, false, true,true},
{false, false, false, true, true, false, false, true, false, false, false, false, false, false, true, false, false, false, false, true, true, true, false, true,true},
{false, false, false, false, true, false, false, true, false, false, false, false, false, false, true, false, true, true, true, true, false, false, false, true,true},
{false, false, false, false, true, false, false, true, false, false, false, false, true, true, true, false, true, false, false, false, false,false, false, true,true},
{false, false, false, false, true, false, false, true, false, false, false, false, true, false, false, false, true, false, false, false, false,false, false, true,true},
{false, false, false, false, true, true, true, true, false, false, false, false, true, false, false, false, true, false, false, false, false,false, false, false,true},
{false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, false, false, false, false,false, false, false,true},
{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,false, false, false,true},
{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,false, false, false,true},
};
Node[][] path = new WalkMaze().queryPathNodes(brick);
for (int i = 0; i < path.length; i++) {
for (int j = 0; j < path[0].length; j++) {
System.out.printf("%-30s",path[i][j]);
}
System.out.println();
}
Queue<Node> queuePath = new ArrayDeque<Node>();
new WalkMaze().queryPath(19,24,path,queuePath);
for (int i = 0; !queuePath.isEmpty(); i++) {
System.out.println(queuePath.remove().toString());
}
}
/**
*
* @param map
* @return
*/
public Queue<Node> queryPaths(boolean[][] map){
try {
Node[][] path = new WalkMaze().queryPathNodes(map);
Queue<Node> queuePath = new ArrayDeque<Node>();
new WalkMaze().queryPath(map.length-1,map[0].length-1,path,queuePath);
return queuePath;
}catch (Exception e){
return null;
}
}
/**
* 给定一个boolean的图
* 用广度遍历生成一个路径图
* @param map
* @return
*/
private Node[][] queryPathNodes(boolean[][] map){
//父队列
Queue<Node> fatherQueue = new ArrayDeque<Node>();
//子队列
Queue<Node> childrenQueue = new ArrayDeque<Node>();
//标记是不是已经被访问
boolean[][] walk = new boolean[map.length][map[0].length];
//存储节点的当前节点的前驱节点
Node[][] nodes = new Node[map.length][map[0].length];
//存储当前节点到起点的距离方格
int[][] dist = new int[map.length][map[0].length];
//创建第一个节点
Node node = new Node(0,0,0);
walk[0][0] = true;//表示当前的节点已经被访问过了
//将第一个节点添加到父亲队列里面
fatherQueue.add(node);
//开始遍历
for (int i = 1; !fatherQueue.isEmpty() ; i++) {
//找到当前节点的所有相通的子节点,并把节点加入子节点的队列中去,
for (;fatherQueue.size()!=0;) {
Node nowNode = fatherQueue.remove();
int x = nowNode.getX();
int y = nowNode.getY();
//遍历四个方向是不是含有节点
//上方向
if(x-1>0&&map[x-1][y]&&!walk[x-1][y]){
//代表当前的节点的上一个节点可以访问,且没有被访问过
//将节点保存到子队列中去
childrenQueue.add(new Node(x-1,y,i));
nodes[x-1][y] = new Node(x,y,i);
walk[x-1][y] = true;
}
//右方向
if(y+1<map[0].length&&map[x][y+1]&&!walk[x][y+1]){
childrenQueue.add(new Node(x,y+1,i));
nodes[x][y+1] = new Node(x,y,i);
walk[x][y+1] = true;
}
//下方向
if(x+1<map.length&&map[x+1][y]&&!walk[x+1][y]){
childrenQueue.add(new Node(x+1,y,i));
nodes[x+1][y] = new Node(x,y,i);
walk[x+1][y] = true;
}
//左方向
if(y-1>0&&map[x][y-1]&&!walk[x][y-1]){
childrenQueue.add(new Node(x,y-1,i));
nodes[x][y-1] = new Node(x,y,i);
walk[x][y-1] = true;
}
}
//将子队列的值赋值给父队列
for (; !childrenQueue.isEmpty();) {
fatherQueue.add(childrenQueue.remove());
}
}
return nodes;
}
private void queryPath(int x,int y,Node[][] paths,Queue<Node> pathNode){
if (x==0&&y==0){
return;
}else {
Node node = new Node(paths[x][y].getX(),paths[x][y].getY(),paths[x][y].getDist()-1);
pathNode.add(node);
queryPath(node.getX(),node.getY(),paths,pathNode);
}
}
}
OK这就是整体的代码,详细的地方我已经打上注释了,不懂的留言
给大家互带一个见面
对这个算法有欢迎的同学可以试着用笔画一下。