Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Interface gráfica indicando para um algoritmo de grafos (k - 1) caminhos (yen) ?

Boa tarde pessoal da alura, tenho um trabalho no qual consiste em realizar uma espécie de GPS de grafos, onde a entrada é: origem, destino, k e a saída é: k rotas, sendo a origem uma coordenada dada em um arquivo CSV de 27.000 linhas representando as arestas do grafo e outro arquivo CSV com 15.000 linhas representando os vértices do grafo.

O algoritmo já está completo e funcionando, mas eu gostaria de saber como seria possível colocar uma interface gráfica (o algoritmo foi feito em Java), indicando as k rotas e modais identificados por cores diferentes...

segue o meu código main (incompleto, essa versão não está indicando os k caminhos e sim vários caminhos iguais) a seguir para quem estiver interessado em ajudar

package tpGrafos;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;

public class Main {
    private static final double raio = 6371000;

    public static void main(String[] args) throws IOException {

        Grafo grafo = new Grafo();
        ArrayList<Vertice> vertices = new ArrayList<>(Grafo.getN());
        ArrayList<Aresta> arestas = new ArrayList<>();
        HashMap<String, Integer> hmap = new HashMap<String, Integer>();
        int key = 0;
        BufferedReader vertex = new BufferedReader(new InputStreamReader(new FileInputStream("vertex.csv")));
        BufferedReader edge = new BufferedReader(new InputStreamReader(new FileInputStream("edge.csv")));

        String linha_v = vertex.readLine();
        String linha_e = edge.readLine();

        while((linha_v = vertex.readLine()) != null) {

            String[] dados_v = linha_v.split(",");
            String id = dados_v[0];


            double lat = Double.parseDouble(dados_v[1]);
            double lon = Double.parseDouble(dados_v[2]);
            int rede;

            if(dados_v[3].equals("road"))
                rede = 0;

            else if(dados_v[3].equals("train"))
                rede = 1;

            else if(dados_v[3].equals("metro"))
                rede = 2;

            else 
                rede = 3;

            Vertice v = new Vertice(id, lat, lon, rede);
            hmap.put(v.getId(), key);
            vertices.add(key, v);
            key++;        

        }

        while((linha_e = edge.readLine()) != null) {

            String[] dados_e = linha_e.split(",");


            String source_id = dados_e[0];
            Vertice inicio = null;

            for (Vertice vert_lista : vertices) 
                if (vert_lista.getId().equals(source_id))
                    inicio = vert_lista;

            String node_id = dados_e[1];
            Vertice fim = null;

            for (Vertice vert_lista : vertices) 
                if (vert_lista.getId().equals(node_id))
                    fim = vert_lista;

            String id = dados_e[2];

            String direction = dados_e[3];

            boolean two_way = direction.equals("TwoWay");

            int rede = 10;

             if(dados_e[4].equals("road"))
                rede = 0;

            else if(dados_e[4].equals("train"))
                rede = 1;

            else if(dados_e[4].equals("metro"))
                rede = 2;

            else if(dados_e[4].equals("tram"))
                rede = 3;

            else if(dados_e[4].equals("crosslayer"))
                rede = 4;

             double peso = haversine(inicio.getLat(), fim.getLat(), inicio.getLon(), fim.getLon());

             Aresta aresta = new Aresta(inicio, fim, id, two_way, rede, peso);
                arestas.add(aresta);

        }

        vertex.close();
        edge.close();

        for(Aresta a : arestas){
            Lista list = new Lista(a.fim, a.peso);
            grafo.getLista_adj()[hmap.get(a.getInicio().getId())].add(list);
            if (a.two_way) {
                list = new Lista(a.inicio, a.peso);
                grafo.getLista_adj()[hmap.get(a.getFim().getId())].add(list);
            }
        }
        grafo.setVertices(vertices);


        int b;
        int k = 3;
        int w = 1;
        while (w <=k) {
            b = 0;
            System.out.println(w + "º Melhor Caminho de " + grafo.getVertices().get(0).getId() + " ate " + grafo.getVertices().get(2).getId() +" :");
            for (Vertice v : Dykstra.dykstra(grafo, grafo.getVertices().get(0), grafo.getVertices().get(4), hmap)) {
                System.out.println(b+ ": "+v.getId());
                b++;
            }
            System.out.println("");
            w++;
        }    

    }

    private static double haversine (double lat1, double lat2, double lon1, double lon2) {
        double lat1_rad =  Math.toRadians(lat1);
        double lat2_rad = Math.toRadians(lat2);
        double delta_lat = Math.toRadians(lat2 - lat1); 
        double delta_lon = Math.toRadians(lon2 - lon1);
        double a = (Math.sin(delta_lat / 2) * Math.sin(delta_lat / 2) +
        Math.cos(lat1_rad) * Math.cos(lat2_rad) * Math.sin(delta_lon / 2) *
        Math.sin(delta_lon / 2));

        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        double d = raio * c;
        return d;    
    }

}
4 respostas

oi Aderbal!

Existem diversas bibliotecas para isso! Acho que a mais atual é essa: https://github.com/jgraph/jgraphx

Mas tem algumas antigas da minha epoca de mestrado: https://jgrapht.org/ https://bfo.com/products/graph/docs/

Esse parece recente mas nao conheço: http://graphstream-project.org/

Opa, isso vai ser de grande ajuda Paulo, mas como eu aplicaria essa lib no meu algoritmo ?

solução!

Aderbal, nao conheço as APIs, mas elas parecem bastante simples de usar de acordo com os tutoriais.

No caso da graphstream, depois de colocar o jar no seu path, esse simples hello mostra bem como adicionar os vertices, arestas e mandar mostrar na tela:

http://graphstream-project.org/doc/Tutorials/Getting-Started/

public class Tutorial1 {
    public static void main(String args[]) {
        Graph graph = new SingleGraph("Tutorial 1");

        graph.addNode("A");
        graph.addNode("B");
        graph.addNode("C");
        graph.addEdge("AB", "A", "B");
        graph.addEdge("BC", "B", "C");
        graph.addEdge("CA", "C", "A");

        graph.display();
    }
}

Basta entao colocar os seus vertices e arestas que estao nas suas arraylists usando essa notação. Aqui link pro javadoc direto deles:

https://data.graphstream-project.org/api/gs-core/current/

muito bem explicado, obrigado mesmo Paulo ! vai ser de grandíssima ajuda !