`

Java实现Dijkstra算法

阅读更多

Dijkstra算法:用于计算图中某一点到其他各点的最短路径。关于Dijkstra算法的说明可以参考 数据结构相关书籍。

为Dijkstra算法设计的类:
1. Node        节点类

2. Edge        边类
3. Graph       图类
4. Dijkstra     Dijkstra算法类
---------------------------------------------------------------------------------------------------------------------------------
Node类:
package com.sabrina.dijkstra;

import java.util.ArrayList;
import java.util.List;

public class Node {

    // 节点编号
    private String id;
    // 从当前节点出发的边的信息列表
    private List outEdges;
   
    public Node(String id) {
        this.id = id;
        outEdges = new ArrayList();
    }
   
    public void addOutEdge(Edge edge) {
        if(edge != null)
            outEdges.add(edge);
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public List getOutEdges() {
        return outEdges;
    }

    public void setOutEdges(List outEdges) {
        this.outEdges = outEdges;
    }
}
 
Edge类:
package com.sabrina.dijkstra;

public class Edge {

    // 边的起始节点编号
    private String startNodeID;
    // 边的末尾节点编号
    private String endNodeID;
    // 边的权值
    private double weight;
   
    public String getStartNodeID() {
        return startNodeID;
    }
    public void setStartNodeID(String startNodeID) {
        this.startNodeID = startNodeID;
    }
    public String getEndNodeID() {
        return endNodeID;
    }
    public void setEndNodeID(String endNodeID) {
        this.endNodeID = endNodeID;
    }
    public double getWeight() {
        return weight;
    }
    public void setWeight(double weight) {
        this.weight = weight;
    }
}
 
Graph类:


 
package com.sabrina.dijkstra;

import java.util.ArrayList;
import java.util.List;

public class Graph {

    // 图中的节点列表
    public List nodeList = null;

    public Graph() {
        nodeList = new ArrayList();
    }

    public List getNodeList() {
        return nodeList;
    }

    // initialize
    public void init() {
        // ************************ Node A ***********************
        Node aNode = new Node("A");
        nodeList.add(aNode);
        // A -> B
        Edge a2bEdge = new Edge();
        a2bEdge.setStartNodeID(aNode.getId());
        a2bEdge.setEndNodeID("B");
        a2bEdge.setWeight(10);
        aNode.addOutEdge(a2bEdge);
        // A -> C
        Edge a2cEdge = new Edge();
        a2cEdge.setStartNodeID(aNode.getId());
        a2cEdge.setEndNodeID("C");
        a2cEdge.setWeight(20);
        aNode.addOutEdge(a2cEdge);
        // A -> E
        Edge a2eEdge = new Edge();
        a2eEdge.setStartNodeID(aNode.getId());
        a2eEdge.setEndNodeID("E");
        a2eEdge.setWeight(30);
        aNode.addOutEdge(a2eEdge);

        // ************************ Node B ***********************
        Node bNode = new Node("B");
        nodeList.add(bNode);
        // B -> C
        Edge b2cEdge = new Edge();
        b2cEdge.setStartNodeID(bNode.getId());
        b2cEdge.setEndNodeID("C");
        b2cEdge.setWeight(5);
        bNode.addOutEdge(b2cEdge);
        // B -> E
        Edge b2eEdge = new Edge();
        b2eEdge.setStartNodeID(bNode.getId());
        b2eEdge.setEndNodeID("E");
        b2eEdge.setWeight(10);
        bNode.addOutEdge(b2eEdge);

        // ************************ Node C ***********************
        Node cNode = new Node("C");
        nodeList.add(cNode);
        // C -> D
        Edge c2dEdge = new Edge();
        c2dEdge.setStartNodeID(cNode.getId());
        c2dEdge.setEndNodeID("D");
        c2dEdge.setWeight(30);
        cNode.addOutEdge(c2dEdge);
       
        // ************************ Node D ***********************
        Node dNode = new Node("D");
        nodeList.add(dNode);
       
        // ************************ Node E ***********************
        Node eNode = new Node("E");
        nodeList.add(eNode);
        // E -> D
        Edge e2dEdge = new Edge();
        e2dEdge.setStartNodeID(eNode.getId());
        e2dEdge.setEndNodeID("D");
        e2dEdge.setWeight(20);
        eNode.addOutEdge(e2dEdge);
       
    }
}
 
Dijkstra类:
package com.sabrina.dijkstra;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class Dijkstra {

    // 起始节点编号
    private String startNodeID;
    // 未被处理的节点集合
    private List sourceNodeIDList = null;
    // 已被处理的节点集合
    private List desNodeIDList = null;

    // '节点编号' 和  '起始节点与当前节点之间的最短路径' 的映射关系
    private Map nodeidShortestRouteMapping = null;
    // '节点编号' 和  '起始节点到当前节点之间的最短路径 的 上一跳节点编号' 的映射关系
    private Map nodeidLastNodeidMapping = null;
    // '节点编号' 和  '节点对象'的 映射关系
    private Map idNodeMapping = null;
   
    public Dijkstra(Graph graph, String startNodeID) {
        this.startNodeID = startNodeID;
       
        // 初始化
        sourceNodeIDList = new ArrayList();
        desNodeIDList = new ArrayList();
        nodeidShortestRouteMapping = new HashMap();
        nodeidLastNodeidMapping = new HashMap();
        idNodeMapping = new HashMap();
       
        for(Node node : graph.getNodeList()) {
            if(node.getId().equals(startNodeID)) {
                desNodeIDList.add(startNodeID);
                // 起始节点到起始节点的最短路径长度为0
                nodeidShortestRouteMapping.put(startNodeID, 0d);
            }
            else {
                sourceNodeIDList.add(node.getId());
                // 非起始节点到起始节点的最短路径长度为 '无穷大'
                nodeidShortestRouteMapping.put(node.getId(), Double.MAX_VALUE);
            }
            // 设置到节点最短路径的上一跳节点为'null'
            nodeidLastNodeidMapping.put(node.getId(), null);
            idNodeMapping.put(node.getId(), node);
        }
    }
   
    public void start() {
        Node nextNode = null;
        Node currentNode = null;
        String nextNodeID = "";
        do {
            if(nextNode == null) {
                currentNode = idNodeMapping.get(startNodeID);
            }
            else {
                currentNode = nextNode;
            }
            nextNodeID = getNextNode(currentNode);
           
            nextNode = idNodeMapping.get(nextNodeID);
            System.out.println("nextNode.id:" + nextNode.getId());
           
            sourceNodeIDList.remove(nextNode.getId());
            System.out.println("sourceNodeIDList:" + sourceNodeIDList.toString());
        } while(sourceNodeIDList.size() > 0);
    }
   
   
    public String getNextNode(Node currentNode) {
        System.out.println("============= currentNode.id: " + currentNode.getId() + " =============");
        double shortestPath = Double.MAX_VALUE;
        String nextNodeID = "";
        //  遍历从当前节点出发的邻接节点
        for(Edge nextEdge : currentNode.getOutEdges()) {
            System.out.println("nextEdge.endNodeid:" + nextEdge.getEndNodeID());
            // 判断 '经过当前节点至邻接节点的距离' < '之前记录的从源节点出发到邻接节点的距离'
            if((nextEdge.getWeight() + nodeidShortestRouteMapping.get(currentNode.getId()))
                    < nodeidShortestRouteMapping.get(nextEdge.getEndNodeID())) {
                // 更新路由表
                nodeidShortestRouteMapping.put(nextEdge.getEndNodeID(),
                        nextEdge.getWeight() + nodeidShortestRouteMapping.get(currentNode.getId()));
                nodeidLastNodeidMapping.put(nextEdge.getEndNodeID(),
                        currentNode.getId());
            }
        }
        // 从未被处理过的节点集合中,取出权值最小的节点
        for(String nodeID : sourceNodeIDList) {
            if(nodeidShortestRouteMapping.get(nodeID) < shortestPath) {
                shortestPath = nodeidShortestRouteMapping.get(nodeID);
                nextNodeID = nodeID;
            }
        }
        if(sourceNodeIDList.size() == 1) // 从未被处理过的节点集合中,取出最后一个节点
            return sourceNodeIDList.get(0);
        return nextNodeID;
    }
   
   
    public Map getNodeidShortestRouteMapping() {
        return nodeidShortestRouteMapping;
    }

    public Map getNodeidLastNodeidMapping() {
        return nodeidLastNodeidMapping;
    }

    public static void main(String[] args) {
        Graph graph = new Graph();
        graph.init();
       
        Dijkstra dijkstra = new Dijkstra(graph, "A");
        dijkstra.start();

        // 打印最终的路由表
        Iterator it = dijkstra.getNodeidShortestRouteMapping().keySet().iterator();
        while(it.hasNext()) {
            String id = it.next();
            System.out.println("nodeId: "  + id + ", shortest length: " + dijkstra.getNodeidShortestRouteMapping().get(id)
                    + ", last nodeId: " + dijkstra.getNodeidLastNodeidMapping().get(id));
        }
    }
}
 
最终执行结果
============= currentNode.id: A =============
nextEdge.endNodeid:B
nextEdge.endNodeid:C
nextEdge.endNodeid:E
nextNode.id:B
sourceNodeIDList:[C, D, E]
============= currentNode.id: B =============
nextEdge.endNodeid:C
nextEdge.endNodeid:E
nextNode.id:C
sourceNodeIDList:[D, E]
============= currentNode.id: C =============
nextEdge.endNodeid:D
nextNode.id:E
sourceNodeIDList:[D]
============= currentNode.id: E =============
nextEdge.endNodeid:D
nextNode.id:D
sourceNodeIDList:[]
nodeId: D, shortest length: 40.0, last nodeId: E
nodeId: E, shortest length: 20.0, last nodeId: B
nodeId: A, shortest length: 0.0, last nodeId: null
nodeId: B, shortest length: 10.0, last nodeId: A
nodeId: C, shortest length: 15.0, last nodeId: B
PS:如有写的不对的,敬请纠正~
  • 大小: 21.9 KB
分享到:
评论

相关推荐

    什么是dijkstra算法,Java和Python如何实现dijkstra算法

    dijkstra算法:什么是dijkstra算法,Java和Python如何实现dijkstra算法 dijkstra算法:什么是dijkstra算法,Java和Python如何实现dijkstra算法 dijkstra算法:什么是dijkstra算法,Java和Python如何实现dijkstra算法...

    java实现Dijkstra算法

    Dijkstra算法通过计算起始顶点到其他顶点的最短路径来解决单源最短路径问题。在示例代码中,我们使用数组distance来记录起始顶点到其他顶点的最短距离。 首先,我们初始化所有顶点的距离为无穷大(用Integer.MAX_...

    Dijkstra算法求最短路径——Java实现

    在这个Java实现中,我们将深入探讨如何利用Dijkstra算法来解决最短路径问题。 首先,我们需要了解一些基本概念。在图论中,图是由节点(顶点)和边构成的。每个边都有一个与之相关的权重,代表了从一个节点到另一个...

    Dijkstra算法java实现

    在这个Java实现中,我们将深入探讨Dijkstra算法的工作原理、如何用Java代码来实现它,以及该算法在实际问题中的应用。 Dijkstra算法的基本思想是通过贪心策略,每次选择当前未访问节点中距离起点最近的一个,并更新...

    基于Dijkstra路由算法的路由软件实现

    在本文中,我们将深入探讨Dijkstra算法的原理、Java实现及其在路由软件中的应用。 **一、Dijkstra算法的基本原理** Dijkstra算法的主要目标是找到图中节点间的最短路径。它采用贪心策略,每次迭代都会找到当前未...

    Dijkstra算法JAVA代码

    以下是一个简单的Dijkstra算法实现框架: ```java import java.util.*; class Node implements Comparable&lt;Node&gt; { int id, distance; // 其他属性,如邻接节点列表 public Node(int id) { this.id = id; ...

    基于java+dijkstra算法实现上海地铁换乘线路的查询+源码+实现原理解析(毕业设计&课程设计&项目开发)

    基于java+dijkstra算法实现上海地铁换乘线路的查询+源码+实现原理解析,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用~ 基于java+dijkstra算法实现上海地铁换乘...

    JAVA实现Dijkstra

    java实现的DIJKSTRA,可以给出图中一点到指定的另一点其中的一个最短路径

    Dijkstra算法的java实现方式及优化.pdf

    本文主要分析了Dijkstra算法的基本原理,并通过Java编程语言实现了该算法,并对该算法的效率进行了优化。 算法的基本思想是,从源点出发,通过不断选择最短距离的路径进行搜索,来确定从源点到各个顶点的最短路径。...

    Dijkstra算法Java实现示例

    以下是Java语言实现Dijkstra算法的一个简单示例,这个示例假设你有一个图的邻接矩阵表示,并且所有边的权重都是正数。 代码定义了一个DijkstraExample类,其中包含了Dijkstra算法的实现。dijkstra方法接受一个图的...

    堆优化的dijkstra算法(dijkstra+邻接表+heap)

    #### 堆优化的Dijkstra算法实现 堆优化的Dijkstra算法主要通过以下几个步骤实现: 1. **初始化**:首先将起点的距离设置为0,其余顶点的距离设置为无穷大;同时将所有顶点加入最小堆中。 2. **提取最小距离顶点**...

    DijkstraAlgorithm:用Java实现Dijkstra算法

    在这个Java实现中,我们将深入理解Dijkstra算法的工作原理,并探讨如何用Java代码来表达这一算法。 Dijkstra算法的基本思想是从起点开始,逐步扩展最短路径,每次选择当前未访问节点中距离源点最近的一个节点,更新...

    基于Java+Dijkstra算法的地铁线路换乘最短路径项目(免费提供全部源码)

    Dijkstra算法实现: 使用优先队列(PriorityQueue)实现Dijkstra算法,以提高效率。 初始化起点节点的距离为0,其余节点距离为无穷大。 重复选择未访问节点中距离最小的节点,更新其邻接节点的距离,直到所有节点都...

    Java实现的Dijkstra最短路径算法.

    在Java编程中,Dijkstra算法通常使用优先队列(如二叉堆)或邻接矩阵来实现。 Dijkstra算法的基本思想是通过逐步扩展最短路径树来找到从起点到所有节点的最短路径。它采用贪心策略,每次选取当前未访问节点中距离...

    ava实现dijkstra算法的最短路径

    Java实现迪杰斯特拉(Dijkstra)算法是图论中的一个重要话题,该算法主要用于寻找有向或无向图中从源节点到其他所有节点的最短路径。在计算机科学领域,这种算法广泛应用在网络路由、地图导航、任务调度等多个场景。...

Global site tag (gtag.js) - Google Analytics