2013.1.5

本文针对Dijkstra算法在特定情况下的不足进行了探讨,并提出了一种基于优先级队列的改进方案,确保了算法能够找到最短路径。通过遍历所有边并使用优先级队列选择最优路径,该方案有效地解决了原有算法存在的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

* Dijkstra Done, All clear;

* 个人想法:

    对于Dijkstra算法,不应该通过(已探测集合S==全部顶点集合V) && (已探测之后的顶点不再设为目的地)作为控制条件,这样会导致如下图情况,得不到最优解;


    应该尽可能的遍历所有的边,因此以(边优先级队列!为空) 为控制条件,使用优先级队列来选择路线,尽快的出现最优解;


* 基于优先级队列的Dijkstra算法@java/DataStructure/unit14

class Graph{
	private Vertex vArr[];
	private int adjMat [] [];
	private int number;
	private int max;

	public Graph(int max){
		this.max=max;
		vArr=new Vertex[max];
		adjMat=new int [max][max];
		number=0;
		for(int i=0; i<max; i++)
			for(int j=0; j<max; j++)
				adjMat[i][j]=0;
	}

	public void add(Vertex vTemp){
		vArr[number++]=vTemp;
		for(int i=0; i<number; i++){
			adjMat[number][i]=0;
			adjMat[i][number]=0;
		}
	}

	public void addEdge(int i, int j, int weight){
		adjMat[i][j]=weight;
	}

	public void dijkstra(){
		Path [] pArr=new Path[number];
		pArr[0]=new Path("0", 0);
		for(int i=1; i<pArr.length; i++) pArr[i]=new Path();
		Queue queue=new Queue(50);
		for(int i=0; i<number; i++){
			if(adjMat[0][i]>0){
				pArr[i].path="0"+i;
				pArr[i].weight=adjMat[0][i];
				queue.insert(new Edge(0, i, adjMat[0][i]));
			}
		}
		while(!queue.isEmpty()){
			Edge eTemp=queue.remove();
			System.out.println("Delete "+vArr[eTemp.start].label+"->"+vArr[eTemp.end].label+", "+eTemp.weight);
			for(int i=0; i<number; i++){
				if(adjMat[eTemp.end][i]>0){
					System.out.println(vArr[eTemp.end].label+"->"+vArr[i].label+", "+adjMat[eTemp.end][i]);
					if(pArr[i].path==null || adjMat[eTemp.end][i]+pArr[eTemp.end].weight<pArr[i].weight){
						pArr[i].path=pArr[eTemp.end].path+i;
						pArr[i].weight=pArr[eTemp.end].weight+adjMat[eTemp.end][i];
						queue.insert(new Edge(eTemp.end, i, adjMat[eTemp.end][i]));
						System.out.println("Insert "+vArr[eTemp.end].label+"->"+vArr[i].label+", "+adjMat[eTemp.end][i]);
					}
				}
			}
		}
		for(Path p: pArr){
			p.display();
		}
	}

	public void displayMat(){
		System.out.println("The Adjacent Matrix is: ");
		System.out.print("   ");
		for(int i=0; i<number; i++){
			System.out.print(vArr[i].label+"  ");
		}
		System.out.println();
		for(int i=0; i<number; i++){
			System.out.print(vArr[i].label+" ");
			for(int j=0; j<number; j++){
				if(adjMat[i][j]<10){
					System.out.print(" "+adjMat[i][j]+" ");
				}
				else System.out.print(adjMat[i][j]+" ");
			}
			System.out.println();
		}
	}

}

class Vertex{
	public char label;

	public Vertex(char label){
		this.label=label;
	}
}

class Edge{
	public int start;
	public int end;
	public int weight;
	public Edge(int start, int end, int weight){
		this.start=start;
		this.end=end;
		this.weight=weight;
	}

	public void display(){
		System.out.println(start+"->"+end+", "+weight);
	}
}

class Queue{
	public Edge [] eArr;
	public int max;
	public int current;

	public Queue(int max){
		this.max=max;
		eArr=new Edge [max];
		current=0;
	}

	public void insert(Edge eTemp){
		int i=current-1;
		for(; i>=0 && eTemp.weight>eArr[i].weight; i--) eArr[i+1]=eArr[i];
		eArr[i+1]=eTemp;
		current++;
	}

	public Edge remove(){
		return eArr[--current];
	}

	public Edge peek(){
		return eArr[current-1];
	}

	public boolean isEmpty(){
		return current==0;
	}

	public boolean isFull(){
		return current==max;
	}

	public void display(){
		for(int i=current-1; i>=0; i--){
			eArr[i].display();
		}
	}
}

class Path{
	public String path;
	public int weight;

	public Path(){
		path=null;
		weight=-1;
	}

	public Path(String str, int ival){
		path=str;
		weight=ival;
	}

	public void display(){
		System.out.println(path+", "+weight);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值