Olá boa noite, estou fazendo um método para achar a árvore geradora mínima usando o algoritmo de Kruskall.
Estou usando conjuntos disjuntos baseado no livro do Thomas H. Cormen.
O livro tem o seguinte algoritmo de Kruskall:
MST-KRUSKAL(G,w)
A <- 0
for cada vértice v E V[G]
do makeSet(v)
ordenar as arestas de E por peso w não decrescente
for cada aresta(u,v) E E, em ordem de peso não decrescente
do if FIND-SET(u) != FIND-SET(v)
then A <- A U (u,v)
UNION(u,v)
return A
Assim implementei uma classe DisjointSet com os métodos makeSet(), find() e union(). e chamo esta no método agmUsandoKruskall2().
Porém em alguns momentos não estou conseguindo pegar alguns componentes dos grafos.
Vou postar a classe e o método.
Se alguém poder ajudar, agradeço.
Desde já muito obrigada.
A classe DisjointSet:
package tp1;
import grafos.Aresta;
import grafos.Grafo;
import grafos.Vertice;
import java.util.Collection;
import java.util.LinkedList;
/**
*
* @author jessica
*/
public class DisjointSet {
// arvore recebe todos os vertices
private LinkedList<Vertice> arvore;
// floresta é a lista que recebe a arvore
private LinkedList<Vertice> floresta;
// associacao ao objeto do grafo
Grafo grafo = null;
// quantidade total dos vertices
private int qtVertice;
// uma lista de vertice
private LinkedList<Vertice> vertice;
public DisjointSet(int numVertice) {
qtVertice = numVertice;
floresta = new LinkedList<Vertice>();
}
/**
*
* @param v
* @return
*/
// recebo um vertice e adiciono este a minha lista de vertice arvore
public LinkedList<Vertice> makeSet(Vertice v){
arvore = new LinkedList<Vertice>();
arvore.add(v);
return arvore;
}
// quero saber se dois vertices estao na mesma arvore
public int find(Vertice x) {
for(int i=0;i<arvore.size();i++){
if (arvore.get(i).id() == x.id()) {
find(x);
// aqui estou retornando o id do vertice
return arvore.get(i).id();
}
}
retorno o id do vertice que recebi
return x.id();
}
// adiciono na lista de arvore se os vertices forem diferentes e se forem iguais adiciono na lista de floresta
public LinkedList<Vertice> union(Vertice u, Vertice v) {
if (u.id() < 0 && v.id() < 0 && u != v) {
if (v.id() < u.id()) {
arvore.add(u);
arvore.add(v);
} else {
floresta.add(u);
floresta.add(v);
}
}
return arvore;
}
}
O método agmUsandoKruskall2():
// este método é da interface que o professor passou e recebe somente o grafo e não o peso
public Collection<Aresta> agmUsandoKruskall2(grafos.Grafo g) {
// criei um vetor para peso, porém não usei
int[] w = new int[g.numeroDeVertices()];
// vetor para retornar as arestas da agm
LinkedList<Aresta> x = null;
LinkedList<Vertice> floresta = new LinkedList<Vertice>();
LinkedList<Vertice> arvore = new LinkedList<Vertice>();
// objeto do conjunto disjunto
DisjointSet conj = new DisjointSet(g.numeroDeVertices());
// como pegar cada vertice de um grafo ?? g.vertices() retorna a coleção de vertices, no caso todos os vertices,
como eu poderia fazer para pegar cada vertice desse grafo ?
for (int i = 0; i < g.vertices().size(); i++) {
System.out.println(g.vertices());
}
// coloquei a lista arvore p/ receber a lista retornada com o vertice adicionado no metodo makeSet
for (int i = 0; i < v.id(); i++) {
arvore = conj.makeSet(v);
// }
// preciso ordenar a lista de arestas adjacentes
Ordena ordena = new Ordena();
LinkedList<Aresta> adjacentes;
for (int k = 0; k < g.vertices(); k++) {
// aqui tentei colocar todos vertices adjacentes de v na lista adjacentes
adjacentes = adjacentes = new (Aresta)g.adjacentesDe(v);
}
Collections.sort(adjacentes, ordena.compare(v, u));
// para cada adjacente eu chamo o metodpo find() e verifico se esses são iguais
for (int i = 0; i < adjacentes.get(i).peso(); i++) {
conj.find(adjacentes.get(i).origem(), adjacentes.get(i).destino());
// a minha lista de aresta x tem que receber os vertices que comparei no metodo find
x = conj.union(adjacentes.get(i).origem(), adjacentes.get(i).destino());
}
return x;
}