Hay topológica tipo de expansión mínimo algoritmo de árbol y gráfico acíclico (Prim + Kruskal)

En primer lugar, clasificación topológica

1, objetivo clasificación topológica

       Para el gráfico acíclico objetivo, clasificación topológica es en realidad para averiguar las dependencias de orden.

alt
       Por encima de la cifra de clasificación topológica es A B C D E F 或 A B D C E F.



2, el algoritmo de pensamiento

       En primer lugar encontrar el vértice a 0º en cola secuencialmente desde la cabecera de la cola cada vez que un ápice equipo (suprimido se puede ver en esta figura), la actualización de este modo la información de los vértices de los bordes de la final, una vez el nuevo vértice de 0 grados de este punto inmediatamente en el equipo hasta que la cola está vacía. Por lo tanto el orden del equipo es en realidad el resultado de la clasificación topológica.



3, Notas

       ¿Cómo mantener el grado de información?用一个哈希表记录除了起始入度就为0的所有结点的入度信息,每次从队列中取出一个顶点就更新这个哈希表即可。

       Cómo ahorrar conjunto de resultados?因为结果是严格要求顺序的,可用动态数组或者链表保存。


4, para lograr

    /**
     * 有向无环图的拓扑排序
     */
    @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;
    }






En segundo lugar, el algoritmo de árbol de expansión mínima (grafo no dirigido)

1, el objetivo algoritmo de árbol de expansión mínimo

       Spanning Tree: la figura mínimo subgrafo conectado de comunicación.即 n-1 条边连接 n 个顶点。

       El número mínimo para generar el objetivo es encontrar todo el peso total del árbol de expansión mínima de un árbol .



2, Prim algoritmo

① Ideas algoritmo

       Seleccione un punto como punto de partida, el punto de partida para la recogida, la selección de un peso mínimo al tiempo que añade al conjunto de resultados desde el conjunto de todos los puntos del borde, y este borde es también aplicada al extremo del conjunto de realizar continuamente la anteriormente operación, hasta que el número alcanza el conjunto de todos los vértices del número de vértices en el dibujo, a continuación, los extremos de algoritmo.

       Este algoritmo es sólo un juego de principio a fin, por lo que se puede configurar la simulación disjuntos-set.

alt

Notas ②

       ¿Cómo escoger el borde más pequeño peso?可以用优先队列来保存所有边,但是出队最小边的时候需要注意,不能让原来结果集里面的顶点成环!


③ lograr
		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 algoritmo

① Ideas algoritmo

       El peso de acuerdo con la orden del lado derecho (de pequeñas a grandes) se añade con el árbol de expansión, el árbol de expansión que contiene hasta V - 1 hasta que los bordes (V es el número de vértices). Corresponde al tiempo inicial para poner todos los vértices como la recogida selectiva, seleccione un borde que serán los bordes inicial y final en un conjunto. Por supuesto, si el lado de inicio y final seleccionado ya está en una colección que está obligado a anular, sólo podrá seleccionar el siguiente flanco.

       Este algoritmo implica varias colecciones, sólo que con disjuntos-set de lograr.

alt

② realización
		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;
	    }
Publicado 54 artículos originales · ganado elogios 5 · Vistas 4595

Supongo que te gusta

Origin blog.csdn.net/cj1561435010/article/details/104828447
Recomendado
Clasificación