Advertisement
eurismarpires

Dijkstra

Jul 29th, 2016
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.44 KB | None | 0 0
  1.  #include <iostream>
  2.     #include <algorithm>
  3.     #include <vector>
  4.     #include <string>
  5.     #include <list>
  6.     #include <limits> // para numeric_limits
  7.     #include <utility> // para pair
  8.     #include <queue> // para priority_queue
  9.     #include <iterator>
  10.     #include <fstream>
  11.     #include <cstdlib>  
  12.     #include <map>
  13.     #include <math.h>
  14. //  #include <CPUTimer.cpp>
  15.     using namespace std;
  16.     #define MAX 99999999999
  17.    
  18.     typedef vector<vector<pair<int,int> > > Grafo;
  19.     typedef map<int, int> VerticesPorGrau;
  20.     Grafo G;
  21.     VerticesPorGrau mapaVerticesPorGrau;
  22.     vector<int> caminho;
  23.     vector<int> minDist;
  24.     vector<int> predecessor;  
  25.              
  26.     void ler_arquivo(Grafo &g);
  27.     int contar_arestas(string nome_arquivo);
  28.     void gravar_matriz_adjacencia(Grafo &g);
  29.     void gravar_grau_vertices(Grafo &g);
  30.     void dijkstra(int &fonte, int &destino);
  31.     int contar_vertices(Grafo &g);
  32.     void calcular_vertices_por_grau(Grafo &g, VerticesPorGrau &m);
  33.     int main(int argc, char** argv)
  34.     {  
  35.     //  cout << "INFORME O NOME DO ARQUIVO QUE CONTEM O GRAFO (Exemplo: \"USA-road-d.NY.gr\") E TECLE ENTER \n" << endl;
  36.         string nome_arquivo;
  37.       //  cin >> nome_arquivo;
  38.         nome_arquivo = "USA-road-d.NY.gr";
  39.         //USA-road-d.NY.gr
  40.          
  41.         //Graph g;
  42.         int qtde_arestas = contar_arestas(nome_arquivo);
  43.         cout << "qtde de arestas encontradas: " << qtde_arestas << endl;
  44.         G.resize(qtde_arestas);                        
  45.         cout << "Lendo o arquivo..." << endl;      
  46.         ler_arquivo(G);                
  47.         int menu_item;
  48.         do{
  49.             cout << "===========DIGITE AS OPCOES SEGUINTES====================" << endl;
  50.             cout << "1 - PARA SALVAR A MATRIZ DE ADJACENCIA EM FORMATO CSV" << endl;
  51.             cout << "2 - PARA SALVAR O GRAU DE CADA VERTICE EM CSV" << endl;
  52.             cout << "3 - EXECUTAR O DIJKSTRA K VEZES" << endl;
  53.             cout << "4 - DADOS SOBRE O GRAFO" << endl;
  54.             cout << "5 - QUANTIDADE DE VERTICES POR GRAU" << endl;            
  55.             cout << "6 - PARA EXECUTAR O DIJKSTRA ESCOLHENDO ORIGEM E DESTINO" << endl;
  56.             cout << "9 - PARA SAIR" << endl;
  57.  
  58.             cin >> menu_item;
  59.        
  60.             switch(menu_item){
  61.              case 1  : gravar_matriz_adjacencia(G);
  62.                break;
  63.              case 2  : gravar_grau_vertices(G);      
  64.                break;
  65.            case 3 :{
  66.                  cout << "Informe o valor do K" << endl;
  67.                  int k;
  68.                  cin >> k;
  69.                  
  70.                 //para percorrer até o último vertice
  71.                 int quantidade_vertices =  contar_vertices(G);
  72.                 //int quantidade_vertices =  100000;                
  73.                  
  74.                 for(int i = 1 ;i <= G.size(); i++) {              
  75.                   int x = G[i].size();
  76.                   int vezes = 0;
  77.                   if(x == 1){          
  78.                     minDist.resize(G.size());
  79.                     predecessor.resize(G.size());
  80.                     cout << "Executando o dijkstra do nó  " << i << " para o nó " << quantidade_vertices <<  endl;                      
  81.                     dijkstra(i,quantidade_vertices);
  82.                     cout << "FIM EXECUCAO" << endl;
  83.                    
  84.                     cout << "Caminho mais curto para o nó " << i << "...." << endl;
  85.                     for(int i=caminho.size()-1;i>=0;i--)
  86.                       cout<<caminho[i]<<"->";                
  87.                     cout << "---------------------" << endl;
  88.                    
  89.                     vezes++;
  90.                     if (vezes >= k)  
  91.                         break;          
  92.                   }        
  93.                 }                
  94.              };
  95.                break;              
  96.              case 4  : {
  97.                  int v =  contar_vertices(G);
  98.                  cout << "O grafo contem :" << v << " vertices e " << qtde_arestas << " arestas. " << endl;
  99.              }      
  100.                break;
  101.              case 5  : {
  102.                  calcular_vertices_por_grau(G,mapaVerticesPorGrau);
  103.                  cout << "---------------------" << endl;
  104.                  cout << "Grau|Qtde de Vertices|"<< endl;
  105.                  cout << "---------------------" << endl;
  106.                  for(int i = 1;i <= mapaVerticesPorGrau.size();i++){
  107.                    cout <<  i << "   |" << mapaVerticesPorGrau[i] << endl;  
  108.                  }
  109.              };      
  110.                break;
  111.              case 6  : {
  112.                 int inicial;
  113.                 cout << "DIGITE O NO FONTE" << endl;
  114.                 cin >> inicial;
  115.                 int final;
  116.                 cout << "DIGITE O NO DESTINO" << endl;
  117.                 cin >> final;                                                                                      
  118.                 cout << "Executando o dijkstra..." << endl;
  119.                 minDist.resize(G.size());
  120.                 predecessor.resize(G.size());              
  121.                 dijkstra(inicial,final);
  122.                 cout << "Caminho mais curto..." << endl;
  123.                 for(int i=caminho.size()-1;i>=0;i--)
  124.                     cout<<caminho[i]<<"->";              
  125.                 cout << endl;
  126.                  
  127.              };break;                                    
  128.              default : exit(0);
  129.             }  
  130.         }while(menu_item < 9);                                            
  131.         return 0;
  132.     }
  133. void dijkstra(int &fonte, int &destino){
  134.     std::ofstream ofs_log_fila ("log_fila_prioridade.txt", std::ofstream::out);      
  135.            for(int i = 0 ;i < G.size(); i++) {
  136.               predecessor[i] = -1;
  137.               minDist[i] = MAX;          
  138.            }          
  139.            minDist[fonte] = 0;
  140.            
  141.            int tamFilaPrioridades = 0;        
  142.            priority_queue<pair<int,int>, vector<pair<int,int> >, greater<pair<int, int> > > Fila;    
  143.            Fila.push(make_pair(fonte,minDist[fonte]));
  144.            tamFilaPrioridades = Fila.size();
  145.            
  146.            ofs_log_fila<<"-------------------------------------------------------------------"<<endl;
  147.            ofs_log_fila<<"Existe "<<tamFilaPrioridades<<" elemento na fila de prioridades"<<endl;
  148.            ofs_log_fila << "Altura do Heap Binario da fila de prioridades: 0" << endl;
  149.            ofs_log_fila<<"-------------------------------------------------------------------"<<endl;
  150.            int cont = 0;
  151.            while(!Fila.empty()){
  152.                ofs_log_fila<<++cont<<endl;
  153.            
  154.                int u = Fila.top().first;
  155.                
  156.                if(u == destino){
  157.                 ofs_log_fila<<"Encontrado o destino! Retornando..."<<endl;
  158.                 ofs_log_fila<<endl;
  159.                    break;
  160.                }              
  161.                Fila.pop();
  162.                
  163.                for(int i=0; i < G[u].size(); i++){
  164.                   int v= G[u][i].first;
  165.                   int w = G[u][i].second;
  166.                  
  167.                   if(minDist[v] > minDist[u]+w){
  168.                      minDist[v] = minDist[u]+w;
  169.                      predecessor[v] = u;                    
  170.                      Fila.push(make_pair(v,minDist[v]));
  171.                   }
  172.                }
  173.                tamFilaPrioridades = Fila.size();
  174.                
  175.                if(Fila.size() == 1){
  176.                    ofs_log_fila<<"Existe "<<tamFilaPrioridades<<" elemento na fila de prioridades"<<endl;
  177.                }else{
  178.                    ofs_log_fila<<"Existem "<<tamFilaPrioridades<<" elementos na fila de prioridades"<<endl;
  179.                }
  180.              
  181.                if(tamFilaPrioridades != 0){
  182.                    ofs_log_fila << "Altura do Heap Binario da fila de prioridades:" << floor(log2(tamFilaPrioridades)) << endl;
  183.                }else{
  184.                    ofs_log_fila << "Altura do Heap Binario da fila de prioridades: 0" << endl;
  185.                }
  186.                ofs_log_fila<<"-------------------------------------------------------------------"<<endl;              
  187.            }
  188.            
  189.            caminho.clear();        
  190.            int p = destino;        
  191.            caminho.push_back(destino);
  192.            
  193.            while(p!=fonte){
  194.              p = predecessor[p];
  195.              caminho.push_back(p);
  196.            }    
  197.            ofs_log_fila.close();                  
  198.     }
  199.        
  200.     void gravar_matriz_adjacencia(Grafo &g){          
  201.         cout << "Gravando a matriz de adjacencia" << endl;
  202.         std::ofstream ofsm ("matriz_adjacencia.csv", std::ofstream::out);
  203.         for(int i = 1 ;i <= G.size(); i++) {
  204.             ofsm << i << ";";          
  205.             for(int j = 0; j < G[i].size(); j++){
  206.                 if(G[i].size() != 0)
  207.                    ofsm  << G[i][j].first << ";";    
  208.               }
  209.             ofsm << "\n";                                                                        
  210.         }      
  211.         ofsm.close();
  212.         cout << "Terminou de gravar a matriz de adjacência" << endl;                          
  213.     }
  214.     void gravar_grau_vertices(Grafo &g){
  215.         //mostrar os graus de cada vérticie
  216.         cout << "Gravando o grau dos vértices" << endl;
  217.         std::ofstream ofs ("graus_verticies.csv", std::ofstream::out);
  218.         ofs << "Vertice;Grau\n";
  219.         for(int i = 1 ;i <= G.size(); i++) {
  220.             if(G[i].size() != 0)
  221.               ofs << i << ";"<<  G[i].size() << "\n";                                                
  222.         }      
  223.         ofs.close();
  224.         cout << "Terminou de gravar o grau dos vertices" << endl;
  225.                
  226.     }
  227.     int contar_vertices(Grafo &g){
  228.         int v = 0;
  229.         for(int i = 1 ;i <= G.size(); i++) {
  230.             if(G[i].size() != 0)
  231.               v++;                                                  
  232.         }                  
  233.         return v;          
  234.     }  
  235.     void ler_arquivo(Grafo &g){
  236.         ifstream infile;
  237.         infile.open("USA-road-d.NY.gr");
  238.        
  239.         if (infile.is_open() && infile.good()){
  240.             string linha;
  241.            
  242.             while(!infile.fail())
  243.             {
  244.                 getline(infile, linha);
  245.                
  246.                 if (linha.substr(0,1).compare("a") == 0){
  247.                     //pega o nó origem do grafo
  248.                     int posicao = linha.find_first_of(" ") + 1;
  249.                     string substr1 = linha.substr(posicao);
  250.                     int posicao_final = substr1.find_first_of(" ");
  251.                     string coluna1 = substr1.substr(0,posicao_final);
  252.                     //pega o nó destino do grafo              
  253.                     posicao = substr1.find_first_of(" ") + 1;
  254.                     substr1 = substr1.substr(posicao);
  255.                     posicao_final = substr1.find_first_of(" ");
  256.                     string coluna2 = substr1.substr(0,posicao_final);              
  257.                    
  258.                     //pega o peso do grafo            
  259.                     posicao = substr1.find_first_of(" ") + 1;
  260.                     substr1 = substr1.substr(posicao);
  261.                     posicao_final = substr1.find_first_of(" ");
  262.                     string coluna3 = substr1.substr(0,posicao_final);  
  263.                    
  264.                     //converte os valores para inteiro e passa para a lista de adjacências
  265.                     int x = atoi(coluna1.c_str());
  266.                     int y = atoi(coluna2.c_str());
  267.                     int z = atoi(coluna3.c_str());                            
  268.                                
  269.                     g[x].push_back(make_pair(y,z));
  270.        
  271.                 }
  272.            }                  
  273.         }
  274.         G = g;
  275.     }
  276. int contar_arestas(string nome_arquivo){
  277.         ifstream infile;
  278.         infile.open(nome_arquivo.c_str());
  279.         int i = 0;
  280.         if (infile.is_open() && infile.good()){
  281.             string linha;
  282.            
  283.             while(!infile.fail())
  284.             {
  285.                 getline(infile, linha);
  286.                
  287.                 if (linha.substr(0,1).compare("a") == 0){
  288.                   i++;        
  289.                 }
  290.            }                  
  291.         }  
  292.         return i;
  293. }
  294. void calcular_vertices_por_grau(Grafo &g, VerticesPorGrau &m){
  295.     for(int i = 1 ;i <= G.size(); i++) {
  296.         int x = G[i].size();
  297.         if(x != 0){            
  298.             x = m[x] = m[x] + 1;
  299.              
  300.          }        
  301.     }                                
  302.        
  303. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement