Dijkstra 算法

 今天又翻了翻算法导论,看了看dijstra算法。兴趣来了就实现了下。完全按照书上的步骤实现,没有使用最小堆等数据结构,使用的邻接表方式表示图。因此实现的算法效率很抵,不过这里只是想通过程序来说明这个算法。不是工程上用的。如果工程上使用,最好用矩阵表示图,然后再使用最小堆。。。。不多说了,直接上代码。

(原理参见算法导论第二版p366)

 

package Graph;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;


public class Dijkstra2 {
	private AdjacencyList adjList = new AdjacencyList();
	public static void main(String[] args) {
		try{
			double[][] matrix = { 
					{ util.max, 5, util.max, util.max, 10 }, 
					{ util.max, util.max, 2, 9, 3 },
					{ 7, util.max, util.max, 6, util.max },
					{ util.max, util.max, 4 , util.max, util.max },
					{ util.max, 2, util.max, 1, util.max } 
					};
			
			Dijkstra2 dijkstra = new Dijkstra2(matrix);
			
			dijkstra.adjList.print();
			dijkstra.calculate(0);
			dijkstra.print();
			
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
   public Dijkstra2(double [][] matrix){
	   adjList = new AdjacencyList(matrix);
   }
   //存储前驱节点
   private int [] pre ;
   //存储距离
   private double [] dist;
   /**
    * @function 计算最近路径
    * @param v 源点
    */
   public void calculate(int v){
	   pre = new int [this.adjList.size()];
	   dist = new double[this.adjList.size()];
	   //s序列,存放
	   boolean [] s = new boolean [this.adjList.size()];
	   
	   //初始化距离
	   Arrays.fill(dist, util.max);
	   //初始化前驱节点
	   Arrays.fill(pre, -1);
	   //初始队列s中没有点
	   Arrays.fill(s, false);
	   
	   //源点的距离为0
	   dist[v] = 0;
	   int gray = v;
	  
	   while(true){
		   //找出距离最小的点
		   double mindis = Double.MAX_VALUE;
		   for(int i = 0 ; i < dist.length ; i++){
			   if(mindis > dist[i] && !s[i]){
				   mindis = dist[i];
				   gray = i;
			   }
		   }
		   //把找到的这个点加入到s队列中
		   s[gray] = true;
		   
		   //======对与gray点有边的点进行松驰=====
		   Node pnode = adjList.get(gray);
		   //向后移一个节点,因为第一个节点是自己。后面的点才是当前节点的后继节点。
		   pnode = pnode.next;
		   while(pnode != null){
			   //后继节点与当前节点的距离 + 当前节点与源点的距离   < 	后继节点到源点的距离
			   if(pnode.weight + mindis < dist[pnode.index]){
				   //后继节点的到源点的距离 更新 为 后继节点与当前节点的距离 + 当前节点与源点的距离
				   dist[pnode.index] = pnode.weight + mindis;
				   //后继节点的前驱节点更新为 当前节点
				   pre[pnode.index] = adjList.get(gray).index;
			   }
			   //下一个后继节点
			   pnode = pnode.next;
		   }
		   
		   //===判断s中是否包含全部的点了
		   boolean con = false;
		   for(boolean b : s)
			   if(b == false){
				   con = true;
				   break;
			   }
		   if(!con)
			   break;
		   
	   }
	   
   }
	
 
	public void print() {
		for(int i = 0 ; i < dist.length ; i++){
			System.out.print(dist[i] + "\t");
			printpath(i);
			System.out.println();
		}
	}

	public void printpath(int v){
		Stack<Integer> stack = new Stack<Integer>(); 
		while(pre[v] >= 0){
			stack.add(pre[v]);
			v = pre[v];
		}
		while(stack.size() > 0)
			System.out.print(stack.pop() + "\t");
	}
   public double getWeight(Node node , int index){
	   while(node != null){
		   int ndx = node.index;
		   if(ndx == index)
			   return node.weight;
		   node = node.next;
	   }
	   return util.max;
   }
}

class AdjacencyList{
	
	private List<Node> adjList = new ArrayList<Node>();
	public AdjacencyList(){};
	
	public int size(){
		return adjList.size();
	}
	public Node get(int index){
		return this.adjList.get(index);
	}
	public List<Node> getData(){
		return this.adjList;
	}
	public AdjacencyList(double [][] matrix){
		for(int i = 0 ; i < matrix.length ; i++){
			double [] vals = matrix[i];
			addData(i , vals);
		}
	}
	
	public void addData(int v , double [] vals){
		Node  node = new Node(v , 0);
		Node head = node;
		for(int j = 0 ; j < vals.length ; j++){
			if(vals[j] < util.max && vals[j] != 0.0){
				node.next = new Node();
				node = node.next;
				node.set( j , vals[j]);
			}
		}
		adjList.add(head);
	}
	
	public void print(){
		for(Node node : adjList){
			while(node != null){
				System.out.print(node.toString() + "\t");
				node = node.next;
			}
			System.out.println();
		}
	}
}


class Node{
	Node next;
	double weight = util.max;
	int index = -1;
	public Node(){
		
	}
	
	public Node(int index , double weight){
		set(index , weight);
	}
	public void set(int index , double weight){
		this.index = index;
		this.weight = weight;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "[ " + index + " , " + weight + " ]"; 
	}
}

class util{
	public static double max = Double.MAX_VALUE;
}

  

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像析等应用至关重要。以下是深度学习的一些关键概念和组成部: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值