El algoritmo de Kruskall no buscará ciclos porque no es eficiente en el rendimiento; Pero intenta crear un componente que sea un árbol y luego conectarlos entre sí. Como sabe, si conecta dos árboles diferentes con un borde nuevo, creará un nuevo árbol y no es necesario verificar los ciclos.
Si nos fijamos en wiki page algoritmo es el siguiente:
1. create a forest F (a set of trees), where each vertex in the graph is a separate tree
2. create a set S containing all the edges in the graph
3. while S is nonempty and F is not yet spanning
a. remove an edge with minimum weight from S
b. if that edge connects two different trees, then add it to the forest, combining
two trees into a single tree
c. otherwise discard that edge.
Debe utilizar Disjoint Set Data Structure para esto. nuevamente desde el wiki:
primero ordene los bordes por peso usando una clasificación de comparación en O (E log E) hora; esto permite que el paso "eliminar un borde con un peso mínimo desde S" funcione en tiempo constante. A continuación, utilizamos una estructura de datos disjuntos (Unión & Buscar) para realizar un seguimiento de qué vértices están en qué componentes . Necesitamos realizar operaciones O (E), dos operaciones 'encontrar' y posiblemente una unión para cada borde. Incluso una estructura simple de datos inconexos , como bosques disjuntos con unión por rango, puede realizar operaciones O (E) en el tiempo O (E log V). Por lo tanto, el tiempo total es O (E log E) = O (E log V).
Creación disjuntos Bosques
Ahora se puede echar un vistazo a Boost Graph Library-Incremental Components parte. Debe implementar algunos métodos: MakeSet, Buscar, Unión, Después de eso puede implementar el algoritmo de kruskall. Todo lo que hace es trabajar con algunos conjuntos, y la forma más simple de hacerlo es usar la lista vinculada.
Cada conjunto tiene un elemento denominado como elemento representativo, que es el primer elemento del conjunto.
1- primer instrumento MakeSet por listas enlazadas:
Esto prepara la estructura de datos disjuntos-conjuntos para el incremental de algoritmo de componentes conectados haciendo cada vértice en el gráfico de un miembro de de su propio componente (o establecer).
Usted sólo debe inicializar cada vértice (elemento) como un elemento representativo de la nueva serie, se puede hacer esto mediante el establecimiento de ellos como ellos mismos padres:
function MakeSet(x)
x.parent := x
2- Implementar encontrar el método:
Encuentra elemento representativo de conjunto que contiene vértice x
:
function Find(x)
if x.parent == x
return x
else
return Find(x.parent)
La pieza if
comprueba que el elemento sea representativo o no. establecemos todos los elementos representativos de los conjuntos como su primer elemento al configurarlos como padres.
3- Y por último cuando tienes todas las cosas anteriores simple parte está implementando Unión método:
function Union(x, y)
xRoot := Find(x) // find representative element of first element(set)
yRoot := Find(y) // find representative element of second element(set)
xRoot.parent := yRoot // set representative element of first set
// as same as representative element of second set
Ahora, ¿cómo se debe ejecutar Kruskall?
Primero ponga todos los nodos en n
conjuntos disjuntos por método MakeSet. En cada paso después de encontrar el borde deseado (no marcado y uno mínimo), encuentre los conjuntos relacionados de sus vértices de punto final por Método Find (sus elementos representativos), si son iguales, suelte este borde porque este borde causa un ciclo, pero Si están en conjuntos diferentes, use Union método para fusionar estos conjuntos. Porque cada conjunto es una unión de árbol de ellos es un árbol.
Puede optimizar esto eligiendo una mejor estructura de datos para conjuntos disjuntos, pero por ahora creo que es suficiente. Si está interesado en estructuras de datos más avanzadas, puede implementar rango forma básica, lo encontrará en wiki, es fácil pero no lo mencioné para evitar el desconcierto.
me corrija si estoy equivocado, pero esto es un árbol, por lo que cada nodo excepto el primer nodo tendría un nodo padre. ¿Has considerado esta implementación? –
@Legend, en el algoritmo de kruskall, durante el tiempo de ejecución del algoritmo tenemos bosque no árbol, por lo que su suposición es incorrecta. –