Boa tarde galera do Alura, a partir do pseudo-código de Djikstra, resolvi desenvolver o meu próprio, com entradas de vértices ao invés de um grafo em si, pois estou utilizando um arquivo .csv para vértices e arestas que me dão um mapa com mais de 20.000 vértices e 10.000 arestas
public Aresta[] Djikstra(Vertice inicial, Vertice destino) {
List<Aresta> Caminho = new ArrayList<>();
PriorityQueue<DijkstraVertice> Unvisited = new PriorityQueue<>();
DijkstraVertice unv[];
DijkstraVertice current = null;
for (Vertice v : this.getVertices()) {
Unvisited.add(new DijkstraVertice(v));
}
unv = new DijkstraVertice[Unvisited.size()];
unv = Unvisited.toArray(unv);
for (DijkstraVertice v : unv) {
if (v.equals(inicial)) {
current = v;
current.setMinPeso(0.0);
Unvisited.remove(inicial);
}
}
while (!Unvisited.isEmpty()) {
for (Aresta a : this.getArestas()) {
if (a.getInicio().equals(current) || (a.isTwo_way() && a.getFim().equals(current))) {
unv = new DijkstraVertice[Unvisited.size()];
unv = Unvisited.toArray(unv);
for (DijkstraVertice v : unv) {
if (v.equals(a.getFim()) || (a.isTwo_way() && v.equals(a.getInicio()))) {
if (v.setMinPeso(a.getPeso())) {
Unvisited.remove(v);
Unvisited.add(v);
}
}
}
}
}
DijkstraVertice prev = current;
current = Unvisited.poll();
current.setPrev(prev);
if (current.equals(destino)) {
int v=0;
while (current.getPrev() != null) {
for (Aresta a : this.getArestas()) {
if ((a.getInicio().equals(current) && a.getFim().equals(current.getPrev()))
|| (a.getFim().equals(current) && a.getInicio().equals(current.getPrev()))) {
Caminho.add(a);
System.out.println(v++ + " -- " + a.getInicio().getId() + " -> " + a.getFim().getId() + " " + a.getRede());
break;
}
}
current = current.getPrev();
}
Collections.reverse(Caminho);
Unvisited.clear();
}
}
Aresta path[] = new Aresta[Caminho.size()];
return Caminho.toArray(path);
}
segue a seguir a classe DijkstraVertice
package grafo;
public class DijkstraVertice extends Vertice implements Comparable<DijkstraVertice> {
private Double peso;
private DijkstraVertice prev;
public DijkstraVertice(String id, double lat, double lon, Rede rede) {
super(id, lat, lon, rede);
this.peso = Double.POSITIVE_INFINITY;
this.prev = null;
}
public DijkstraVertice(Vertice v) {
super(v.getId(), v.getCoord().getX(), v.getCoord().getY(), v.getRede());
this.peso = Double.POSITIVE_INFINITY;
this.prev = null;
}
public DijkstraVertice(Vertice v, Double peso) {
super(v.getId(), v.getCoord().getX(), v.getCoord().getY(), v.getRede());
this.peso = peso;
this.prev = null;
}
public boolean setMinPeso(Double peso) {
boolean change = peso < this.peso;
if (change)
this.peso = peso;
return change;
}
@Override
public int compareTo(DijkstraVertice arg0) {
return this.peso.compareTo(arg0.peso);
}
public DijkstraVertice getPrev() {
return prev;
}
public void setPrev(DijkstraVertice prev) {
this.prev = prev;
}
}
não consegui notar nada de errado, mas por volta da 30ª linha do algoritmo, onde eu tive que colocar
for (DijkstraVertice v : unv) {
if (v.equals(a.getFim()) || (a.isTwo_way() && v.equals(a.getInicio()))) {
if (v.setMinPeso(a.getPeso())) {
Unvisited.remove(v);
Unvisited.add(v);
aparentemente ele está fazendo isso várias e várias vezes, em um djikstra comum que encontrei na internet, para uma origem e um destino, o padrão achado foi de um caminho com tamanho 150, sendo que para a mesma origem e o mesmo destino, meu código achou um caminho de tamanho 7000 !
Não quero desistir do meu código nem quero pegar nada da net, sei que ele está próximo de ficar aperfeiçoado, mas preciso de ajuda com essa parte !