求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代表你创建的类。

下面是这个程序运行后的截图

温馨提示:答案为网友推荐,仅供参考
第1个回答  2009-05-05
一楼正解
离散数学中对这一个算法有详细解释。。
大概思路就是
如果设置点A 为起点,则找到所有与A相临的点
有几个点就几条路。。然后挨个往下找。
在与所有端点相临的所有点中,如果有发现B(终点)则这条路就是最近的
如果考虑每条路的长度不是相等的情况下,那就得把所有点都遍历完了 再判断哪条路最短
如果向量是单向的,那又更简单了

如果要用程序实现,一个可伸缩数据结构
一个循环就OK了
第2个回答  2009-05-05
用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;
}
第3个回答  2009-05-04
这好像是离散数学里的最短路径算法吧

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网