There topological sort the minimum spanning tree algorithm and acyclic graph (Prim + Kruskal)

First, topological sorting

1, topological sorting target

       For the target acyclic graph, topological sorting is actually to find out the order dependencies.

Alt
       Above the figure in topological sorting it is A B C D E F 或 A B D C E F.



2, thinking algorithm

       First find the 0 ° vertex sequentially enqueued from the queue head each time a team apex (deleted can be seen from this figure), thereby updating the information of the vertices of the edges of the end, once the new 0-degree vertex of this point immediately into the team until the queue is empty. Thus the order of the team is actually the result of topological sorting.



3, Notes

       How to maintain the degree of information?用一个哈希表记录除了起始入度就为0的所有结点的入度信息,每次从队列中取出一个顶点就更新这个哈希表即可。

       How to save result set?因为结果是严格要求顺序的,可用动态数组或者链表保存。


4, to achieve

    /**
     * 有向无环图的拓扑排序
     */
    @Override
    public List<E> topologicalSort() {
        List<E> result = new ArrayList<>();
        Map<E, Integer> table = new HashMap<>();           //哈希表维护所有结点的入度
        Queue<Vertex<E, V>> queue = new LinkedList<>();
        Set<E> keys = vertices.keySet();
        for (E e : keys) {
            Vertex<E, V> vertex = vertices.get(e);
            int size = vertex.inEdges.size();
            if (size == 0)
                queue.offer(vertex);                    //队列初始化
            else
                table.put(e, vertex.inEdges.size());     //哈希表初始化
        }
        while (!queue.isEmpty()) {
            Vertex<E, V> vertex = queue.poll();
            result.add(vertex.element);
            for (Edge<E, V> edge : vertex.outEdges) {
                Integer size = table.get(edge.to.element);
                if (--size == 0) {
                    queue.offer(edge.to);               //一旦结点的入度为0立刻入队
                    table.remove(edge.to.element);
                } else {
                    table.put(edge.to.element, size);    //更新由出队结点指向的其他结点的入度
                }
            }
        }
        return result;
    }






Second, the minimum spanning tree algorithm (undirected graph)

1, the minimum spanning tree algorithm target

       Spanning Tree: FIG minimal connected subgraph of communication.即 n-1 条边连接 n 个顶点。

       The minimum number to generate the target is to find all of the total weight of the minimum spanning tree of a tree .



2, Prim algorithm

① algorithm ideas

       Select a point as a starting point, the starting point to the collection, selecting a minimum weight while adding to the result set from the set of all points of the edge, and this edge is also applied to the end of the set of continuously performing the above operation, until the number reaches the set of all vertices of the number of vertices in the drawing, then the algorithm ends.

       This algorithm is only one set from beginning to end, so it can be set disjoint-set simulation.

Alt

② Notes

       How to pick the smallest weight edge?可以用优先队列来保存所有边,但是出队最小边的时候需要注意,不能让原来结果集里面的顶点成环!


③ achieve
		private Set<EdgeInfo<E, V>> prim() {
	        Set<EdgeInfo<E, V>> result = new HashSet<>();
	        Set<Vertex<E, V>> addedVertices = new HashSet<>();
	        int desPointSize = vertices.size();
	        PriorityQueue<Edge<E, V>> queue = new PriorityQueue<>(new Comparator<Edge<E, V>>() {
	            @Override
	            public int compare(Edge<E, V> o1, Edge<E, V> o2) {
	                return weightAbout.compareWeight(o1.weight, o2.weight);
	            }
	        });
	
	        Iterator<Vertex<E, V>> it = vertices.values().iterator();
	        Vertex<E, V> vertex = it.next();
	        for (Edge<E, V> edge : vertex.outEdges)
	            queue.offer(edge);              //初始化优先队列
	        addedVertices.add(vertex);
	
	        while (!queue.isEmpty() && addedVertices.size() < desPointSize) {
	            Edge<E, V> minEdge = queue.poll();      //取出权值最小的边
	            Vertex<E, V> toVertex = minEdge.to;
	            if (addedVertices.contains(toVertex))   //避免成环
	                continue;
	            toVertex.outEdges.forEach((Edge<E, V> edge) -> {
	                if (!addedVertices.contains(edge.to))   //避免添加重复边
	                    queue.offer(edge);     //每次都将取出边终点的出度边入队
	            });
	            result.add(minEdge.castToInfo());
	            addedVertices.add(toVertex);
	        }
	        return result;
	    }


3, Kruskal algorithm

① algorithm ideas

       The weight according to the order of the right side (small to large) is added with the spanning tree, the spanning tree containing up to V - 1 until the edges (V is the number of vertices). Corresponds to the initial time to put all vertices as a separate collection, select an edge that will be the start and end edges into one set. Of course, if the selected start and end side already in a collection that is bound to ring, you can only choose the next edge.

       This algorithm involves multiple collections, only with disjoint-set to achieve.

Alt

② realization
		private Set<EdgeInfo<E, V>> kruskal() {
	        Set<EdgeInfo<E, V>> result = new HashSet<>();
	        PriorityQueue<Edge<E, V>> queue = new PriorityQueue<>(new Comparator<Edge<E, V>>() {
	            @Override
	            public int compare(Edge<E, V> o1, Edge<E, V> o2) {
	                return weightAbout.compareWeight(o1.weight, o2.weight);
	            }
	        });
	        int desEdgeSize = vertices.size() - 1;
	        UnionFind<E> uf = new UnionFind<>();
	        edges.forEach((Edge<E, V> edge) -> {    //初始化队列
	            queue.offer(edge);
	        });
	        vertices.values().forEach((Vertex<E, V> vertex) -> {    //初始化集合
	            uf.makeSet(vertex.element);
	        });
	
	        while (!queue.isEmpty() && result.size() < desEdgeSize) {
	            Edge<E, V> minEdge = queue.poll();
	            Vertex<E, V> fromVertex = minEdge.from;
	            Vertex<E, V> toVertex = minEdge.to;
	            if (uf.isSame(fromVertex.element, toVertex.element))     //避免成环
	                continue;
	
	            result.add(minEdge.castToInfo());
	            uf.union(fromVertex.element, toVertex.element);
	        }
	        return result;
	    }
Published 54 original articles · won praise 5 · Views 4595

Guess you like

Origin blog.csdn.net/cj1561435010/article/details/104828447