求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 算法 | 图最短路径算法使用场景 | 求解图中任意两个点之间的最短路径 | 邻接矩阵存储图数据 | 弗洛伊德算法总结 )

最短路求两点间最短路径的改进的Dijkstra算法及其matlab实现

1091.二维矩阵中的最短路径

最短路

求图中任意两点之间最短路径有啥算法?

最短路径算法