求java实现矩阵图上任意两点的最短路径源码
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求java实现矩阵图上任意两点的最短路径源码相关的知识,希望对你有一定的参考价值。
基本要求
以矩阵表示地图,
1,1,1,1,1,1,1,1,1,1,1
1,0,1,0,1,0,0,0,0,0,1
1,0,1,0,0,0,1,0,1,1,1
1,0,0,0,1,0,1,0,0,0,1
1,0,1,1,0,0,1,0,0,1,1 0代表可以通过,1代表不可通过
1,0,1,0,1,1,0,1,0,0,1
1,0,0,0,0,0,0,0,1,0,1
1,0,1,0,1,0,1,0,1,0,1
1,0,0,1,0,0,1,0,1,0,1
1,1,1,1,1,1,1,1,1,1,1
可以任意设定起点和终点,可以任意设定地图,输出路径和步数。
比如我要找从右下角的那个1到矩阵第三行第4列的那个元素的最短路径,应该怎么做。我想要的是java源代码,最好能附上一些解释。想了好久,没想出来,拜托各位帮忙了
我用的是递归调用方法,有个小问题就是在打印步数的时候是返向的,原因是就是程序不断的调用自己,到最后判断基值位准退出调用。这才开始从栈里取出方法进行执行的原因。
代码欣赏:
public static int step = 1;
public static StringBuffer printStep = new StringBuffer();
public static int[][] maze =1,1,1,1,1,1,1,1,1,1,1,
1,0,1,0,1,0,0,0,0,0,1 ,
1,0,1,0,0,0,1,0,1,1,1 ,
1,0,0,0,1,0,1,0,0,0,1 ,
1,0,1,1,0,0,1,0,0,1,1 ,// 0代表可以通过,1代表不可通过
1,0,1,0,1,1,0,1,0,0,1 ,
1,0,0,0,0,0,0,0,1,0,1 ,
1,0,1,0,1,0,1,0,1,0,1 ,
1,0,0,1,0,0,1,0,1,0,1 ,
1,1,1,1,1,1,1,1,1,1,1 ;
public static void main(String[] args)
int i, j; //循环记数变量
Sample.way(1, 1);//二维数组起始值从下标1,1开始
System.out.println("起点从坐标 x = 1, y = 1开始");
System.out.println("终点坐标是 x = 8, y = 9结束");
System.out.println("这是迷宫图表");
System.out.println(" 0 1 2 3 4 5 6 7 8 9 10");
System.out.println(" +---+---+---+---+---+---+---+---+---+---+---+---+---+");
for(i = 0; i < 10; i++)
System.out.print(" " + i + "‖");
for(j = 0; j < 11; j++)
System.out.print("-" + maze[i][j] + "-‖");
System.out.println("");
System.out.println(" +---+---+---+---+---+---+---+---+---+---+---+---+---+");
//打印显示步数
System.out.print(printStep.toString());
public static boolean way(int x, int y)
if(maze[8][9] == 2)//代表递归终止条件(也就是当走出出口时标记为 2)
return true;
else
if(maze[y][x] == 0)
maze[y][x] = 2;
/*
* 下面if判断条件代表当前坐标为基点,
* 根据判断对当前位置进行递归调用:如:
* 往上、往右上、往右、往右下、往下、
* 往左下、往左、往左上的坐标是否可走,
* 判断是否可走的返回条件是:
* 2代表可通过、1代表不能通过、3表示已经走过,但是未能走通。
*/
if(way(x, y - 1))
printStep.append("第 " + step + " 步的所走的位置是 x = " + x + " y = " + y + "\\n");
step++;
return true;
else if(way(x + 1, y - 1))
printStep.append("第 " + step + " 步的所走的位置是 x = " + x + " y = " + y + "\\n");
step++;
return true;
else if(way(x + 1 , y))
printStep.append("第 " + step + " 步的所走的位置是 x = " + x + " y = " + y + "\\n");
step++;
return true;
else if(way(x + 1, y + 1))
printStep.append("第 " + step + " 步的所走的位置是 x = " + x + " y = " + y + "\\n");
step++;
return true;
else if(way(x, y + 1))
printStep.append("第 " + step + " 步的所走的位置是 x = " + x + " y = " + y + "\\n");
step++;
return true;
else if(way(x - 1, y + 1))
printStep.append("第 " + step + " 步的所走的位置是 x = " + x + " y = " + y + "\\n");
step++;
return true;
else if(way(x - 1, y))
printStep.append("第 " + step + " 步的所走的位置是 x = " + x + " y = " + y + "\\n");
step++;
return true;
else if(way(x - 1, y - 1))
printStep.append("第 " + step + " 步的所走的位置是 x = " + x + " y = " + y + "\\n");
step++;
return true;
else
maze[y][x] = 3;
return false;
else
return false;
复制代码前需要楼主自己创建个 类
Sample.way(1, 1);这句代码是我的类的静态调用,改下XXXXX.way(1, 1);
XXXXX代表你创建的类。
下面是这个程序运行后的截图
参考技术A 一楼正解离散数学中对这一个算法有详细解释。。
大概思路就是
如果设置点A 为起点,则找到所有与A相临的点
有几个点就几条路。。然后挨个往下找。
在与所有端点相临的所有点中,如果有发现B(终点)则这条路就是最近的
如果考虑每条路的长度不是相等的情况下,那就得把所有点都遍历完了 再判断哪条路最短
如果向量是单向的,那又更简单了
如果要用程序实现,一个可伸缩数据结构
一个循环就OK了 参考技术B 用Dijkstra算法,找到的是最短路径,返回的是从起点到终点的每个坐标:
import java.awt.Point;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
static List<Point> dij(final int[][] map, int startX, int startY, int endX, int endY)
int w = map.length;
int h = map[0].length;
final int[][] dist = new int[w][h];
Point[][] previous = new Point[w][h];
for (int i = 0; i < map.length; i++)
for (int j = 0; j < map[i].length; j++)
dist[i][j] = Integer.MAX_VALUE;
previous[i][j] = null;
dist[startX][startY]=0;
Point[] Q = new Point[w * h];
for(int i=0;i<w;i++)
for(int j=0;j<h;j++)
Q[(i*h)+j]=new Point(i, j);
class Comp implements Comparator<Point>
public int compare(Point o1, Point o2)
if (o1 == o2)
return 0;
if (o1 == null)
return -10000;
if (o2 == null)
return 10000;
return dist[o2.x][o2.y] - dist[o1.x][o1.y];
Comp comp = new Comp();
int lastElement = w * h - 1;
while (lastElement >= 0)
Arrays.sort(Q, 0, lastElement + 1, comp);
Point p = Q[lastElement--];
if (p == null)
break;
for (int k = -1; k <= 1; k++)
for (int m = -1; m <= 1; m++)
if (k != 0 || m != 0)
Point neighbor = new Point(p.x + k, p.y + m);
if (p.x + k >= 0
&& p.y + m >= 0
&& p.x + k < w
&& p.y + m < h
&& map[p.x + k][p.y + m] == 0
&& Arrays.binarySearch(Q, 0, lastElement + 1,
neighbor, comp) >= 0)
int cost;
if(dist[p.x][p.y]==Integer.MAX_VALUE) cost = Integer.MAX_VALUE;
else cost = 1000 + dist[p.x][p.y];
if (cost < dist[p.x + k][p.y + m])
dist[p.x + k][p.y + m] = cost;
previous[p.x+k][p.y+m] = new Point(p.x, p.y);
Point start = new Point(startX, startY);
Point destination = new Point(endX, endY);
LinkedList<Point> llist = new LinkedList<Point>();
llist.add(destination);
Point movingPoint = new Point(destination);
while(!movingPoint.equals(start))
Point path = previous[movingPoint.x][movingPoint.y];
if(path==null) break;
llist.add(new Point(path));
movingPoint.setLocation(path);
Collections.reverse(llist);
return llist;
参考技术C 这好像是离散数学里的最短路径算法吧
以上是关于求java实现矩阵图上任意两点的最短路径源码的主要内容,如果未能解决你的问题,请参考以下文章
数据结构与算法图最短路径算法 ( Floyed 算法 | 图最短路径算法使用场景 | 求解图中任意两个点之间的最短路径 | 邻接矩阵存储图数据 | 弗洛伊德算法总结 )