拓扑排序-Dijkstra算法

来源:互联网 发布:淘宝网店设计教程 编辑:程序博客网 时间:2024/05/18 01:08
package com.ygy.test.sort;import lombok.Getter;import lombok.Setter;import org.springframework.util.CollectionUtils;import java.util.*;/** * Created by guoyao on 2017/10/11. *///拓扑排序public class Dijkstra {    //定义顶点信息    private static class Vertex {        @Getter @Setter        private  int indegree;  //入度        @Getter @Setter        private String name ;  //顶点信息        //广度优先搜索新增字段        @Getter @Setter        private int deepPath = Integer.MAX_VALUE ;  //路径深度 初始化为最小        @Getter @Setter        private Boolean isKnown = false ;   //路口是否已探  初始化为false        @Getter @Setter        private Vertex preShortVertex ;        public boolean isKnown() {            return isKnown ;        }        public Vertex(String name) {            this.name=name;            indegree = 0 ;   //初始入度为0        }        @Override        public boolean equals(Object o) {            if (this == o) return true;            if (o == null || getClass() != o.getClass()) return false;            Vertex vertex=(Vertex) o;            return name.equals(vertex.name);        }        @Override        public int hashCode() {            return name.hashCode();        }    }    //定义拓扑关系图    private static class TopoGraph {        //dijkstra   修改关系为map 带入权重        public Map<Vertex, Map<Vertex,Integer>> relMap=new HashMap<>();  //顶点与节点关系        public Set<Vertex> vertices=new HashSet<>();  //所有节点信息        //添加顶点关系图        public boolean addRelVertex(Vertex start, Vertex end,Integer weight) {            //根据name判断重复            vertices.add(start);            vertices.add(end);            Map<Vertex,Integer> adjcents=relMap.get(start);  //相邻节点信息            if (CollectionUtils.isEmpty(adjcents)) {                adjcents = new HashMap<>();            }            if (adjcents.containsKey(end)) {                return false;            }            adjcents.put(end,weight);            int indegree=end.getIndegree();            end.setIndegree(++indegree);    //入度+1            relMap.put(start, adjcents);            return true;        }    }    public static List<Vertex> dijkstra(TopoGraph topoGraph,Vertex root) {        PriorityQueue<Vertex> knownQueue=new PriorityQueue<>(                (x,y)-> x.getDeepPath() - y.getDeepPath() > 0 ? 1: - 1        );        List<Vertex> resultList=new ArrayList<>();        root.setIsKnown(true);        root.setDeepPath(0);        knownQueue.add(root);        //最小堆结构,构造最近数据        while (!knownQueue.isEmpty()) {            Vertex minVertex=knownQueue.remove();   //移出最小deep节点            minVertex.setIsKnown(true);             //标记为已知            resultList.add(minVertex);            Map<Vertex, Integer> relAdj=topoGraph.relMap.get(minVertex);            if (!CollectionUtils.isEmpty(relAdj)) {                for (Vertex vertex : relAdj.keySet()) {                    if (!vertex.isKnown()) {                        Integer weight=relAdj.get(vertex);                        //比较已有的deep值,找出最小路线                        if (minVertex.getDeepPath() + weight < vertex.getDeepPath()) {                            knownQueue.remove(vertex);   //移出已有的                            vertex.setDeepPath((weight + minVertex.getDeepPath()));                            knownQueue.add(vertex);                            vertex.preShortVertex=minVertex;                        }                    }                }            }        }       return resultList;    }    public static void printShortPath(List<Vertex> list) {        if (CollectionUtils.isEmpty(list)) {            return;        }        for (Vertex vertex : list) {            int count = 0 ;            while (vertex != null) {                if (count != 0) {                    System.out.print("<----");                }                System.out.print(vertex.getName()+ ":"+ vertex.getDeepPath());                vertex = vertex.preShortVertex;                count ++ ;            }            System.out.println();        }    }    public static void main(String[] args) throws Exception  {        Vertex vertexA=new Vertex("A");        Vertex vertexB=new Vertex("B");        Vertex vertexC=new Vertex("C");        Vertex vertexD=new Vertex("D");        Vertex vertexE=new Vertex("E");        TopoGraph topoGraph=new TopoGraph();        topoGraph.addRelVertex(vertexA, vertexB,5);        topoGraph.addRelVertex(vertexA, vertexC,2);        topoGraph.addRelVertex(vertexC, vertexD,3);        topoGraph.addRelVertex(vertexC, vertexB,2);        topoGraph.addRelVertex(vertexB, vertexD,2);        topoGraph.addRelVertex(vertexB, vertexE,15);        topoGraph.addRelVertex(vertexD, vertexE,4);        printShortPath(dijkstra(topoGraph, vertexA));    }        //A:0        //C:2<----A:0        //B:4<----C:2<----A:0        //D:5<----C:2<----A:0        //E:9<----D:5<----C:2<----A:0}
原创粉丝点击