用java求最短路径问题,求源程序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用java求最短路径问题,求源程序相关的知识,希望对你有一定的参考价值。

不要随便复制几个程序就往里贴OK?
有高手能给个源程序么?
分不是问题啊,最主要是感谢!
发自肺腑的感谢! 很急的
javajavajavajavajavajavajavajavajavajavajavajava
看清题意啊。。。。继续等

import java.util.Vector;
public class Link
private Vector link = new Vector();
// private Link next = null;
public Link()


public boolean addNode(Node setNode)//增加一个节点
setNode = checkNode(setNode);
if(setNode != null)
this.link.addElement((Node)setNode);
return true;

return false;


public void delNode(Node setNode) //删除一个节点
if(!this.link.isEmpty())
for(int i=0;i < this.link.size(); i++)

if(setNode.getPos() == ((Node)this.link.elementAt(i)).getPos())
this.link.remove(i);
//System.out.println("asdfasdfas:"+this.link.size());
break;





public Node checkNode(Node setNode)//判断节点是否在链表里面并取得两者的最佳值
if(!this.link.isEmpty() && setNode!=null)
for(int i=0;i < this.link.size(); i++)

if(setNode.getPos() == ((Node)this.link.elementAt(i)).getPos())
if(setNode.getStep() < ((Node)this.link.elementAt(i)).getStep())
setNode = (Node)this.link.elementAt(i);
this.link.remove(i);

else
return null;
break;



return setNode;


public boolean isEmpty()
return this.link.isEmpty();


public Node getBestNode() //得到最好的节点
Node tmpNode = null;
if(!this.link.isEmpty())
tmpNode = (Node)this.link.elementAt(0);
//System.out.println("tmpNodeStep:"+tmpNode.getStep());
//System.out.print("OpenNode(pos,step):");
for(int i=1;i < this.link.size(); i++)

//System.out.print("("+((Node)this.link.elementAt(i)).getPos()+","+((Node)this.link.elementAt(i)).getStep()+")");
if(tmpNode.getJudgeNum() >= ((Node)this.link.elementAt(i)).getJudgeNum())
tmpNode = (Node)this.link.elementAt(i);



return tmpNode;




public class FindBestPath
private char[][] map = null;//地图
private int maxX,maxY;//最大的地图边界大小
Node startNode = null;//入口
Node endNode = null;//出口
private int endX,endY;
/*初始化
*@param setMap 地图
*@param setX,setY 边界值
//////////*@param startNode 入口
//////////*param endNode 出口
*@param sX,sY:开始点
*@param eX,eY:结束点
*/
public FindBestPath(char[][] setMap,int setX,int setY,int sX,int sY,int eX,int eY)
this.map = setMap;
this.maxY = setX - 1; //x,y互换
this.maxX = setY - 1; //x,y互换
//this.startNode = sNode;
//this.endNode = eNode;

Node sNode = new Node();
Node eNode = new Node();

sNode.setFarther(null);
sNode.setPos(posToNum(sX,sY));
sNode.setStep(0);
eNode.setPos(posToNum(eX,eY));

this.startNode = sNode;
this.endNode = eNode;

this.endX = eX;//numToX(eNode.getPos());
this.endY = eY;//numToY(eNode.getPos());



public int posToNum(int x,int y)//从xy坐标获得编号
return (x+y*(this.maxY+1));


public int numToX(int num)//从编号获得x坐标
return (num%(this.maxY+1));


public int numToY(int num)//从编号获得y坐标
return (int)(num/(this.maxY+1));


public boolean checkVal(int x,int y)//判断是否为障碍
//System.out.println("map["+x+"]["+y+"]="+map[x][y]);
if(this.map[x][y] == 'N')
return false;
else
return true;


public int judge(Node nowNode)//一定要比实际距离小
//System.out.println("nowNodePos:"+nowNode.getPos());
int nowX = numToX(nowNode.getPos());
int nowY = numToY(nowNode.getPos());
int distance = Math.abs((nowX-this.endX))+Math.abs((nowY-this.endY));
// System.out.println("distance:"+distance);
return distance;


public Node getLeft(Node nowNode)//取得左节点
int nowX = numToX(nowNode.getPos());
int nowY = numToY(nowNode.getPos());
Node tmpNode = new Node();
if(nowY > 0)//判断节点是否到最左
if(checkVal(nowX,nowY-1))
tmpNode.setFarther(nowNode);
tmpNode.setPos(posToNum(nowX,nowY-1));
tmpNode.setStep(nowNode.getStep()+1);
tmpNode.setJudgeNum(tmpNode.getStep()+judge(tmpNode));
return tmpNode;


return null;


public Node getRight(Node nowNode)//取得右节点
int nowX = numToX(nowNode.getPos());
int nowY = numToY(nowNode.getPos());
Node tmpNode = new Node();
if(nowY < this.maxX)//判断节点是否到最左
if(checkVal(nowX,nowY+1))
tmpNode.setFarther(nowNode);
tmpNode.setPos(posToNum(nowX,nowY+1));
tmpNode.setStep(nowNode.getStep()+1);
tmpNode.setJudgeNum(tmpNode.getStep()+judge(tmpNode));
return tmpNode;


return null;


public Node getTop(Node nowNode)//取得上节点
int nowX = numToX(nowNode.getPos());
int nowY = numToY(nowNode.getPos());
Node tmpNode = new Node();
if(nowX > 0)//判断节点是否到最左
if(checkVal(nowX-1,nowY))
tmpNode.setFarther(nowNode);
tmpNode.setPos(posToNum(nowX-1,nowY));
tmpNode.setStep(nowNode.getStep()+1);
tmpNode.setJudgeNum(tmpNode.getStep()+judge(tmpNode));
return tmpNode;


return null;


public Node getBottom(Node nowNode)//取得下节点
int nowX = numToX(nowNode.getPos());
int nowY = numToY(nowNode.getPos());
Node tmpNode = new Node();
if(nowX < this.maxY)//判断节点是否到最左
if(checkVal(nowX+1,nowY))
tmpNode.setFarther(nowNode);
tmpNode.setPos(posToNum(nowX+1,nowY));
tmpNode.setStep(nowNode.getStep()+1);
tmpNode.setJudgeNum(tmpNode.getStep()+judge(tmpNode));
return tmpNode;


return null;


public Link getBestPath()//寻找路径
Link openLink = new Link();//没有访问的路径
Link closeLink = new Link();//访问过的路径
Link path = null;//最短路径
Node bestNode = null;

Node tmpNode = null;

openLink.addNode(this.startNode);
while(!openLink.isEmpty())//openLink is not null

bestNode = openLink.getBestNode();//取得最好的节点
//System.out.println("bestNode:("+numToX(bestNode.getPos())+","+numToY(bestNode.getPos())+")step:"+bestNode.getJudgeNum());
if(bestNode.getPos()==this.endNode.getPos())

/*this.endNode.setStep(bestNode.getStep()+1);
this.endNode.setFarther(bestNode);
this.endNode.setJudgeNum(bestNode.getStep()+1);*/
path = makePath(bestNode);
break;

else

tmpNode = closeLink.checkNode(getLeft(bestNode));
if(tmpNode != null)
//System.out.println("("+numToY(tmpNode.getPos())+","+numToX(tmpNode.getPos())+")");
openLink.addNode(tmpNode);

tmpNode = closeLink.checkNode(getRight(bestNode));
if(tmpNode != null)
// System.out.println("("+numToY(tmpNode.getPos())+","+numToX(tmpNode.getPos())+")");
openLink.addNode(tmpNode);

tmpNode = closeLink.checkNode(getTop(bestNode));
if(tmpNode != null)
// System.out.println("("+numToY(tmpNode.getPos())+","+numToX(tmpNode.getPos())+")");
openLink.addNode(tmpNode);

tmpNode = closeLink.checkNode(getBottom(bestNode));
if(tmpNode != null)
// System.out.println("("+numToY(tmpNode.getPos())+","+numToX(tmpNode.getPos())+")");
openLink.addNode(tmpNode);

openLink.delNode(bestNode);
closeLink.addNode(bestNode);


return path;


public Link makePath(Node lastNode)//制造路径
Link tmpLink = new Link();
Node tmpNode = new Node();
int x,y;
tmpNode = lastNode;
if(tmpNode != null)
do
x=numToX(tmpNode.getPos());
y=numToY(tmpNode.getPos());
System.out.println("map["+x+"]["+y+"]="+map[x][y]);
tmpLink.addNode(tmpNode);
tmpNode = tmpNode.getFarther();
while(tmpNode != null);
else

System.out.println("Couldn't find the path!");

return tmpLink;

/**
* @param args the command line arguments
*/
public static void main(String[] args)
char[][] map =
'Y', 'N', 'z', 'y', 'x', 'w', 'v', 'N', 'N', 'N',
'Y', 'N', '1', 'N', 'N', 'N', 'u', 't', 'N', 'N',
'N', '1', '2', '1', '1', '1', 'N', 's', 'N', 'N',
'N', 'N', '1', 'N', '9', 'N', 'q', 'r', 'N', 'N',
'N', 'N', '1', 'N', 'n', 'o', 'p', 'N', 'N', 'N',
'N', '4', '5', '6', 'm', 'N', 'N', 'N', 'N', 'N',
'N', '3', 'N', '5', 'l', 'k', 'j', 'N', 'N', 'N',
'N', 'N', '3', '4', 'N', 'd', 'i', 'd', 'N', 'N',
'N', '1', 'N', 'N', '1', 'N', 'h', 'N', 'N', 'N',
'N', '1', 'N', 'N', '1', 'N', 'g', 'N', 'N', 'N',
'N', 'a', 'b', 'c', 'd', 'e', 'f', 'N', 'N', 'N'
;
/*map[x][y]
*如上所示:maxY=10 maxX=11 横的代表maxY,竖的代表maxX 可以自己替换
*地图的读取是
*for(i=1;i<行的最大值;i++)
* for(j=1;j<列的最大值;j++)
* map[i][j] = 地图[i][j]
*/
Link bestPath = new Link();
/*startNode.setFarther(null);
startNode.setPos(21);
startNode.setStep(0);

//endNode.setFarther(startNode);
endNode.setPos(79);
//endNode.setStep(0);*/

FindBestPath path = new FindBestPath(map, 11, 10, 10, 1, 0, 2);
//FindBestPath path = new FindBestPath(map, 11, 10, startNode, endNode);

bestPath = path.getBestPath();
//bestPath.printLink();





public class Node
private int step;//从入口到该节点经历的步数
private int pos;//位置
private Node farther;//上一个结点
private int judgeNum;
public Node()

public void setStep(int setStep)
this.step = setStep;

public int getStep()
return this.step;

public void setPos(int setPos)
this.pos = setPos;

public int getPos()
return this.pos;

public void setFarther(Node setNode)
this.farther = setNode;;

public Node getFarther()
return this.farther;

public void setJudgeNum (int setInt)
this.judgeNum = setInt;;

public int getJudgeNum()
return this.judgeNum;

参考技术A csdn太令我失望了 ....... :(

class CShortPath

private:
class Edge

private:
int dest; //the operation of the other vertex of edge
int weight;//quan zhi
Edge *link;

;
class Vertex

private:
int adj;//顶点编号
Edge *link;
int Visited; //biao ji
;

public:
void InitE(Vertex head[],int j,int k,int weight);
void short_path(int v,int w);
void creat_adj_list();
CShortPath();
virtual ~CShortPath();
;
void CShortPath::creat_adj_list()

Vertex head[15];
for(int i=0;i<15;i++)

head[i].link=NULL;
head[i].adj=i;//mingzi
head[i].name="站点";

InitE(head,0,1,140);
InitE(head,1,2,675);
InitE(head,2,3,409);
InitE(head,3,4,534);
InitE(head,4,5,511);
InitE(head,5,6,842);
InitE(head,6,7,1100);
InitE(head,7,8,639);
InitE(head,8,9,607);
InitE(head,9,10,255);
InitE(head,2,11,367);
InitE(head,11,12,622);
InitE(head,11,13,825);
InitE(head,13,14,651);
InitE(head,4,14,349);
InitE(head,2,8,902);
InitE(head,2,9,672);
InitE(head,6,8,967);

void CShortPath::InitE(Vertex head[],int j,int k,int weight)

Edge *p;
p=new Edge[sizeof(Edge)];
p->dest=k;
p->link=head[j].link;
p->weight=weight;
head[j].link=p;
p=new Edge[sizeof(Edge)];
p->dest=j;
p->link=head[k].link;
p->weight=weight;
head[k].link=p;

void CShortPath::short_path(int v,int w)

creat_adj_list();
int adj;
int Distance[25];
Edge *q;
int edges;
edges=1;
q=new Edge[sizeof(Edge)];
for(int j=0;j<25;j++)

Distance[j]=Max;
head[j].Visited=0;

q=head[v].link;
while(q!=NULL)

Distance[q->dest]=q->weight;
q=q->link;

q=head[v].link;
head[v].Visited=1;
while(edges<24)

edges++;
Min=Max;
for(int i=0;i<25;i++)

if(head[i].Visited==0&&Min>Distance[i])

Min=Distance[i];
adj=i;


head[adj].Visited=1;
q=head[adj].link;
while(q!=NULL)

if(head[q->dest].Visited==0&&
Distance[adj]+q->weight<Distance[q->dest])

Distance[q->dest]=Distance[adj]+q->weight;

q=q->link;




本程序参考了风云的最短路径代码( http://member.nease.com/~cloudwu),
并加以改进和优化:
1、把原来用于存放已处理节点的堆栈改为(store_queue)队列,这样在从
sort_queue队列出列时可直接放入store_queue中。
2、解除了地图大小的限制(如果有64K内存限制时,地图大小只能是180x180)
3、删除了原程序中的一些冗余,见程序中的注释。
4、程序继续使用dis_map数组保存各点历史历史最佳距离,也包含了某点是否已经
经过的信息,虽然这样做可能会比使用链表多用一些内存,但是在搜索时可以
节省不时间。
5、程序更具有实用性,可直接或修改后运用于你的程序中,但请你使用该代码后
应该返回一些信息给我,如算法的改进或使用于什么程序等。
本程序可以用Borland C++或DJGPP编译,并附带有一个数据文件 map.dat,
保存有地图的数据,(注:该地图文件格式与风云的原代码的地图格式不一样)
算法描述:
findpath()

把S点加入树根(各点所在的树的高度表示从S点到该点所走过的步数);
把S点加入排序队列(按该点到E点的距离排序+走过的步数从小到大排序);
1、排序队列sort_queue中距离最小的第一个点出列,并保存入store_queue中
2、从出列的点出发,分别向4个(或8个)方向中的一个各走出一步
3、并估算第2步所走到位置到目标点的距离,并把该位置加入树,
最后把该点按距离从小到大排序后并放入队列中。(由trytile函数实现)。
4、如果该点从四个方向上都不能移动,则把该点从store_queue中删除
5、回到第一点,直到找到E点则结束
从目标点回溯树,直到树根则可以找到最佳路径,并保存在path[]中

-------------------------------------------------------------------------*/
//#define NDEBUG
#include <stdio.h>
#include <conio.h>
#include <assert.h>
#include <stdlib.h>
#include <mem.h>

#define tile_num(x,y) ((y)*map_w+(x)) //将 x,y 坐标转换为地图上块的编号
#define tile_x(n) ((n)%map_w) //由块编号得出 x,y 坐标
#define tile_y(n) ((n)/map_w)

#define MAPMAXSIZE 180 //地图面积最大为 180x180,如果没有64K内存限制可以更大
#define MAXINT 32767

//树结构, 比较特殊, 是从叶节点向根节点反向链接,方便从叶节点找到根节点
typedef struct tree_node *TREE;

struct tree_node
int h; //节点所在的高度,表示从起始点到该节点所有的步数
int tile; //该节点的位置
TREE father; //该节点的上一步
;

//链接结构,用于保存处理过的和没有处理过的结点
typedef struct link_node *LINK;

struct link_node
TREE node;
int f;
LINK next;
;

LINK sort_queue; // 保存没有处理的行走方法的节点
LINK store_queue; // 保存已经处理过的节点 (搜索完后释放)

unsigned char * map; //地图数据
unsigned int * dis_map; //保存搜索路径时,中间目标地最优解

int map_w,map_h; //地图宽和高
int start_x,start_y,end_x,end_y; //地点,终点坐标

// 初始化队列
void init_queue(void)

sort_queue=(LINK)malloc(sizeof(*sort_queue));
sort_queue->node=NULL;
sort_queue->f=-1;
sort_queue->next=(LINK)malloc(sizeof(*sort_queue));
sort_queue->next->node=NULL;
sort_queue->next->f=MAXINT;
sort_queue->next->next=NULL;

store_queue=(LINK)malloc(sizeof(*store_queue));
store_queue->node=NULL;
store_queue->f=-1;
store_queue->next=NULL;


// 待处理节点入队列, 依靠对目的地估价距离插入排序
void enter_queue(TREE node,int f)

LINK p=sort_queue,father,q;
while(f>p->f)
father=p;
p=p->next;
assert(p);

q=(LINK)malloc(sizeof(*q));
assert(sort_queue);
q->f=f,q->node=node,q->next=p;
father->next=q;


// 将离目的地估计最近的方案出队列
TREE get_from_queue(void)

LINK bestchoice=sort_queue->next;
LINK next=sort_queue->next->next;
sort_queue->next=next;

bestchoice->next=store_queue->next;

Top

3 楼keikei007(keikei)回复于 2004-06-21 19:16:02 得分 0
store_queue->next=bestchoice;
return bestchoice->node;


// 释放栈顶节点
void pop_stack(void)

LINK s=store_queue->next;
assert(s);
store_queue->next=store_queue->next->next;
free(s->node);
free(s);


// 释放申请过的所有节点
void freetree(void)

int i;
LINK p;
while(store_queue)
p=store_queue;
free(p->node);
store_queue=store_queue->next;
free(p);

while (sort_queue)
p=sort_queue;
free(p->node);
sort_queue=sort_queue->next;
free(p);



// 估价函数,估价 x,y 到目的地的距离,估计值必须保证比实际值小
int judge(int x,int y)

int distance;
distance=abs(end_x-x)+abs(end_y-y);
return distance;


// 尝试下一步移动到 x,y 可行否
int trytile(int x,int y,TREE father)

TREE p=father;
int h;
if (map[tile_num(x,y)]!=' ') return 1; // 如果 (x,y) 处是障碍,失败
//这一步用来判断(x,y)点是否已经加入队列,多余可以删除,因为dis_map已经
//保存该点是否已经保存
//while (p)
// if (x==tile_x(p->tile) && y==tile_y(p->tile)) return 1; //如果 (x,y) 曾经经过,失

// p=p->father;
//
h=father->h+1;
if (h>=dis_map[tile_num(x,y)]) return 1; // 如果曾经有更好的方案移动到 (x,y) 失败
dis_map[tile_num(x,y)]=h; // 记录这次到 (x,y) 的距离为历史最佳距离

// 将这步方案记入待处理队列
p=(TREE)malloc(sizeof(*p));
p->father=father;
p->h=father->h+1;
p->tile=tile_num(x,y);
enter_queue(p,p->h+judge(x,y));
return 0;


// 路径寻找主函数
int * findpath(void)

TREE root;
int i,j;
int * path;
memset(dis_map,0xff,map_h*map_w*sizeof(*dis_map)); //填充dis_map为0XFF,表示各点未
曾经过
init_queue();
root=(TREE)malloc(sizeof(*root));
root->tile=tile_num(start_x,start_y);
root->h=0;
root->father=NULL;
enter_queue(root,judge(start_x,start_y));
for (;;)
int x,y,child;
TREE p;
root=get_from_queue();
if (root==NULL)
return NULL;

x=tile_x(root->tile);
y=tile_y(root->tile);
gotoxy(x+1,y+1);
putchar('\'');
if (x==end_x && y==end_y) break; // 达到目的地成功返回

child=trytile(x,y-1,root); //尝试向上移动
child&=trytile(x,y+1,root); //尝试向下移动
child&=trytile(x-1,y,root); //尝试向左移动
child&=trytile(x+1,y,root); //尝试向右移动
//child&=trytile(x+1,y-1,root);//尝试向右上移动
//child&=trytile(x+1,y+1,root); //尝试向右下移动
//child&=trytile(x-1,y+1,root); //尝试向左下移动
//child&=trytile(x-1,y-1,root); //尝试向左上移动

if (child!=0)
pop_stack(); // 如果四个方向均不能移动,释放这个死节点


// 回溯树,将求出的最佳路径保存在 path[] 中
path=(int*)malloc((root->h+2)*sizeof(int));
assert(path);
for (i=0;root;i++)
path[i]=root->tile;
root=root->father;

path[i]=-1;
freetree();
return path;


void printpath(int *path)

int i;
if(path==NULL) return ;
for (i=0;path[i]>=0;i++)
gotoxy(tile_x(path[i])+1,tile_y(path[i])+1);
cprintf(".");



int readmap(void)

FILE *f;
int i,j;
f=fopen("map.dat","r");
assert(f);
fscanf(f,"%d,%d\n",&map_w,&map_h);
map=malloc(map_w*map_h+1);
assert(map);
for(i=0;i<map_h;i++)
fgets(map+tile_num(0,i),map_w+2,f);
fclose(f);
start_x=-1,end_x=-1;
for (i=0;i<map_h;i++)
for (j=0;j<map_w;j++)
if (map[tile_num(j,i)]=='s') map[tile_num(j,i)]=' ',start_x=j,start_y=i;
if (map[tile_num(j,i)]=='e') map[tile_num(j,i)]=' ',end_x=j,end_y=i;

assert(start_x>=0 && end_x>=0);
dis_map=malloc(map_w*map_h*sizeof(*dis_map));
assert(dis_map);
return 0;


void showmap(void)

int i,j;
clrscr();
for (i=0;i<map_h;i++)
gotoxy(1,i+1);
for (j=0;j<map_w;j++)
if (map[tile_num(j,i)]!=' ') cprintf("O");
else cprintf(" ");

gotoxy(start_x+1,start_y+1);
cprintf("s");
gotoxy(end_x+1,end_y+1);
cprintf("e");


int main()

int * path;
readmap();
showmap();
getch();
path=findpath();
printpath(path);
if(dis_map) free(dis_map);
if(path) free(path);
if(map) free(map);
getch();
return 0;


我做过的,以前我用的是呀虎,花了1000分啊!!
我包准对,相信我吧~~
参考技术B .本回答被提问者采纳 参考技术C 问个问题 什么叫最短路经?
最短路径是指什么意思啊?最上层路径?
还是什么
参考技术D 终于有人认真回答了
以前也有人问过
结果没人好好答
这次不错

以上是关于用java求最短路径问题,求源程序的主要内容,如果未能解决你的问题,请参考以下文章

用Dijkstra算法求最短路径的MATLAB程序

用Dijkstra算法求最短路径

求最短路径问题 送货郎问题

UVa 1599 理想路径(反向BFS 求最短路径 )

用C或C++实现求最短路径的Dijkstra算法

求c++ 程序 网络上两点间的最短路径