java实现迪克斯特拉算法

来源:互联网 发布:mac 怎么创建xlsx文档 编辑:程序博客网 时间:2024/05/21 11:32
package com.jd.crawler;import java.util.*;/** * Created by leixingbang on 2017/10/10. * 用来实现迪克斯特拉算法,求最短路径 */public class Dijkstra {    //初始化所有的节点信息    private static final String[] nodes = {"start", "A", "B","C","E","F", "end"};    //尚未探测的节点    private static Set<String>unvisitedNodes=new HashSet<String>();    //设置没有路径的标志    private static long NOWAY_SIGN = Long.MAX_VALUE;    private static String []parents=new String[nodes.length];    //地图    private static long graph[][] = new long[nodes.length][nodes.length];    //cost表    private static long cost[][] = new long[nodes.length][nodes.length];    //将地图进行初始化,默认所有节点之间都没有路径连接    static {        for (int i = 0; i < nodes.length; i++) {            for (int j = 0; j < graph[i].length; j++) {                graph[i][j] = NOWAY_SIGN;            }        }        for(int i=0;i<nodes.length;i++)        {            unvisitedNodes.add(nodes[i]);        }    }    /**     * 对于消耗进行初始化     */    public static void initCost() {        for(int i=0;i<nodes.length;i++)            for(int j=0;j<graph[i].length;j++)            {                cost[i][j]=graph[i][j];            }    }    public static void initParents(String node)    {        for(int i=0;i<graph[getIndex(node)].length;i++)        {           if(graph[getIndex(node)][i]<NOWAY_SIGN)           {               parents[i]=node;           }        }    }    /**     * 构造地图     */    public static void initGraph(String node) {        graph[getIndex("start")][getIndex("A")] = 6;        graph[getIndex("start")][getIndex("B")] = 2;        graph[getIndex("start")][getIndex("end")]=10;        graph[getIndex("start")][getIndex("C")] = 1;        graph[getIndex("C")][getIndex("E")] = 1;        graph[getIndex("E")][getIndex("F")] = 1;        graph[getIndex("F")][getIndex("end")] = 1;        graph[getIndex("B")][getIndex("A")] = 20;        graph[getIndex("B")][getIndex("end")] = 5;        graph[getIndex("A")][getIndex("end")] = 1;        for (int i = 0; i < nodes.length; i++) {            for (int j = 0; j < graph[i].length; j++) {                if(graph[i][j]< NOWAY_SIGN)                    graph[j][i]=graph[i][j];                if(i==j)                    graph[i][j]=0;            }        }        initCost();        initParents(node);    }    /**     * 根据节点的名称获取下标     *     * @param nodeName     * @return     */    public static int getIndex(String nodeName) {        for (int i = 0; i < nodes.length; i++) {            if (nodes[i].equals(nodeName))                return i;        }        return -1;    }    public static String getNodeNameByIndex(int index) {        return nodes[index];    }    public static List<String> getNeighbors(String node) {        List<String> neighbors = new ArrayList<String>();        for (int i = 0; i < graph[getIndex(node)].length; i++) {            if (graph[getIndex(node)][i] < NOWAY_SIGN)                neighbors.add(getNodeNameByIndex(i));        }        return neighbors;    }    /**     * 在已知的节点node中获取最近的邻居节点(该节点为从未探测过的邻居节点)     * @param unvisitedNodes     * @param node     * @return     */    public static String getLowstCostNode(Set<String> unvisitedNodes, String node) {        long lowstDes = NOWAY_SIGN;        String lowstDesNeighbor = null;        for (String neighbor : unvisitedNodes) {            if (cost[getIndex(node)][getIndex(neighbor)] < lowstDes) {                lowstDes = cost[getIndex(node)][getIndex(neighbor)];                lowstDesNeighbor = neighbor;            }        }        return lowstDesNeighbor;    }    public static void vistNode(String node)    {        System.out.println(node + "->");        unvisitedNodes.remove(node);    }    public static void broadIterate(String node) {        vistNode(node);        while (!unvisitedNodes.isEmpty())        {            String lowCostNeighbor=getLowstCostNode(unvisitedNodes,node);            if(lowCostNeighbor!=null) {                //访问最短距离的节点                vistNode(lowCostNeighbor);                //获取所有的邻居节点                List<String> neighbors = getNeighbors(lowCostNeighbor);                //只取尚访问的邻居节点                neighbors.retainAll(unvisitedNodes);                for (String neighbor : neighbors) {                    long dest = cost[getIndex(node)][getIndex(lowCostNeighbor)] + graph[getIndex(lowCostNeighbor)][getIndex(neighbor)];                    //假如已经 a--c的路径是由a--c的最短路径,d是c的邻居节点,那么由a到d的最短路径,就会出现在a--c--d 即a经过c再经过d的路径                    //或者                    if (dest < cost[getIndex(node)][getIndex(neighbor)]) {                        parents[getIndex(neighbor)] = lowCostNeighbor;                        System.out.println(String.format("更新 [%s]->[%s]的距离由%s变为%s", node, neighbor, cost[getIndex(node)][getIndex(neighbor)], dest));                        cost[getIndex(node)][getIndex(neighbor)] = dest;                    }                }            }        }    }    public static void iteratorParents(String node)    {        System.out.print(node);        while (parents[getIndex(node)]!=null)        {            if(node.equals(parents[getIndex(node)]))            {                break;            }            System.out.print("->" + parents[getIndex(node)]);            node=parents[getIndex(node)];        }    }    public static void main(String[] args) {        Dijkstra.initGraph("A");        broadIterate("A");        iteratorParents("E");    }}

原创粉丝点击