Di62028

ijert-dijkstra3.c

Sep 4th, 2020
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.46 KB | None | 0 0
  1. /* TO FIND THE SHORTEST PATH OF A GRAPH USING DJIKSTRA ALGORITHM */
  2. #include<stdio.h>
  3. #include<limits.h>/* Maximum Number of Nodes in a Graph */
  4.  
  5. /// Bibliotecas adicionadas por mim
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <stdbool.h>
  9. /// ---
  10.  
  11. #define MAXNODE 10  // Número máximo de Cidades: 9 (uma a menos)
  12. #define PERM 1
  13. #define TENT 2
  14. #define infinity INT_MAX  // Inteiro máximo
  15.  
  16.  
  17.  
  18. typedef struct NODELABEL
  19. {
  20.     int predecessor;
  21.     int length; /* Optimal distance from Source */
  22.     int label; /* label is tentative or permanent */
  23. }NODELABEL;
  24.  
  25.  
  26. /*
  27.     A função abaixo foi retirada do artigo "Implementation Of Shortest Path Algorithm Using In C"
  28.     publicado no International Journal of Engineering Research & Technology por P.Manikandan e S.Yuvarani,
  29.     e pode ser acessado através do endereço eletrônico abaixo:
  30.     https://www.ijert.org/research/implementation-of-shortest-path-algorithm-using-in-c-IJERTV2IS60569.pdf
  31. */
  32. /*
  33.     Function: Short path Prototype:int Short Path(a, n, s, t, path, dist)
  34.  
  35.     Input:a-Adjacency Matrix   describing   the graph n-Number of Nodes in the graphs-Source Nodet-Target Node or Sink Node
  36.  
  37.     Output:Path -list  of  optimal  path  from source   to sink   dist -Minimum   Distance between source and sink
  38.  
  39.     Returns:0 -if   there   is   no   path   count indicating  the  number  of  nodes  along  the optimal path, otherwise
  40. */
  41. int ShortPath( a, n, s, t, path, dist )
  42. int  a[MAXNODE][MAXNODE], n, s, t, path [MAXNODE], *dist;
  43. {
  44.     NODELABEL state[MAXNODE];int i, k, min, count;
  45.     int rPath[MAXNODE];
  46.     *dist=0;
  47.     /* Initialize all nodes as tentative nodes */
  48.     for(i=1; i<=n; i++){
  49.             state[i].predecessor=0;
  50.             state[i].length=infinity;
  51.             state[i].label=TENT;
  52.     }/* Make source Node as Permanent */
  53.     state[s].predecessor=0;
  54.     state[s].length=0;state[s].label=PERM;
  55.     /* Start from source node */
  56.     k=s;
  57.     do{/* Check all the paths from Kth node and find their distanceform K node */
  58.         for(i=1; i<=n; i++){
  59.             /* -ve if no direct path, 0 if to the same otherwise directpath */
  60.             if(a[k][i]>0 && state[i].label==TENT){
  61.                 if(state[k].length+a[k][i]<state[i].length){
  62.                     state[i].predecessor=k;state[i].length=state[k].length+a[k][i];
  63.                 }
  64.             }
  65.         }/* Find the tentatively labeled node with smaller cost */
  66.         min=infinity;
  67.         k=0;
  68.         for(i=1; i<=n; i++){
  69.             if(state[i].label==TENT && state[i].length<min){
  70.                 min=state[i].length;k=i;
  71.             }
  72.         }/* Is Source Or Sink Node is Isolated */
  73.         if(k==0)
  74.             return(0);
  75.         state[k].label=PERM;
  76.     }while(k!=t);/* Store Optimal Path */
  77.     k=t;
  78.     count=0;
  79.     do{
  80.         count = count + 1;
  81.         rPath[count]=k;
  82.         k=state[k].predecessor;
  83.     }while(k!=0);/* Reverse nodes since algorithm stores path in reversedirection */
  84.  
  85.     for(i=1; i<=count; i++)
  86.         path[i]=rPath[count-i+1];
  87.     for(i=1; i<count; i++)
  88.         *dist+=a[path[i]][path[i+1]];
  89.  
  90.     return(count);
  91. }
  92. /* Fim da função ShortPath */
  93.  
  94.  
  95. typedef struct{
  96.     char cidade1[21];
  97.     char cidade2[21];
  98.     int distancia;
  99. } Rota;
  100.  
  101.  
  102. int verifica_se_esta_no_vetor(char vetor[][21], char palavra[], int tamanho_do_vetor){
  103.  
  104.     for (int i = 0; i < tamanho_do_vetor; i++){
  105.         if (strcmp(palavra, vetor[i]) == 0){
  106.             return 1;
  107.         }
  108.     }
  109.  
  110.     return 0;
  111. }
  112.  
  113. int procura_caminhos_entre_cidades(Rota rotas_ptr[], char cidade1[], char cidade2[], int arestas){
  114.  
  115.     for(int i = 0; i < arestas; i++){
  116.         if (strcmp((rotas_ptr + i)->cidade1, cidade1) == 0 && strcmp((rotas_ptr + i)->cidade2, cidade2) == 0){
  117.             return (rotas_ptr + i)->distancia;
  118.         }
  119.     }
  120.  
  121.     return 0;
  122. }
  123.  
  124.  
  125. /// MAIN
  126.  
  127. void main(){
  128.  
  129.  
  130.     printf("Digite o nome do arquivo de entrada: ");
  131.     char nome_do_arquivo[100];
  132.     scanf("%s", &nome_do_arquivo[0]);
  133. //  char nome_do_arquivo[] = "teste.txt";
  134.  
  135.     /// Abre o arquivo e verifica se foi ok
  136.     FILE *arquivo;
  137.     arquivo = fopen(nome_do_arquivo, "r");
  138.     if (arquivo == NULL){
  139.         printf("Erro na abertura do aqruivo\n");
  140.         exit(1);
  141.     }
  142.  
  143.     int arestas = 0;
  144.  
  145.     /// Armazena a primeira linha do arquivo de entrada
  146.     fscanf(arquivo, "%d", &arestas);
  147.  
  148.     Rota *rotas_ptr = (Rota*) malloc(arestas * sizeof(Rota));
  149.  
  150.     /// Continua lendo o arquivo com as entradas e armazenando os valores
  151.     for(int i = 0; i < arestas; i++){
  152.  
  153.         fscanf(arquivo, "%s", (rotas_ptr + i)->cidade1);
  154.         fscanf(arquivo, "%s", (rotas_ptr + i)->cidade2);
  155.         fscanf(arquivo, "%d", &(rotas_ptr + i)->distancia);
  156.  
  157.     }
  158.  
  159.     int qt_cidades = 0;
  160.     char cidades[1000][21]; // Número máximo de cidades: 1000
  161.  
  162.     /// Preenche um vetor com os nomes das cidades
  163.  
  164.     ///     Para as cidades à esquerda no arquivo
  165.     for(int i = 0; i < arestas; i++){
  166.         char cid[21];
  167.  
  168.         strcpy(cid, (rotas_ptr + i)->cidade1);
  169.  
  170.         /// Verifica se a cidade já foi adicionada ao vetor
  171.         int v = verifica_se_esta_no_vetor(cidades, cid, arestas);
  172.         if (v == 0){
  173.             strcpy(cidades[qt_cidades], cid);
  174.             qt_cidades++;
  175.         }
  176.     }
  177.  
  178.     ///     Para as cidades à direita no arquivo
  179.     for(int i = 0; i < arestas; i++){
  180.         char cid[21];
  181.  
  182.         strcpy(cid, (rotas_ptr + i)->cidade2);
  183.  
  184.         /// Verifica se a cidade já foi adicionada ao vetor
  185.         int v = verifica_se_esta_no_vetor(cidades, cid, arestas);
  186.         if (v == 0){
  187.             strcpy(cidades[qt_cidades], cid);
  188.             qt_cidades++;
  189.         }
  190.     }
  191.  
  192.     /// Lê as cidades de origem e destino e atribui o valor
  193.     char origem[21] = "";
  194.     char destino[21] = "";
  195.  
  196.     fscanf(arquivo, "%s", origem);
  197.     fscanf(arquivo, "%s", destino);
  198.  
  199.     // Cria a matriz/ grafo
  200.     int (*grafo)[qt_cidades] = malloc(qt_cidades * qt_cidades * sizeof(grafo[0][0]));
  201.  
  202.     // Preenche a matriz/ grafo inicialmente com zeros
  203.     for (int i = 0; i < qt_cidades; i++){
  204.         for(int j = 0; j < qt_cidades; j++){
  205.             grafo[i][j] = 0;
  206.         }
  207.     }
  208.  
  209.     /// Este FOR preenche a matriz/ grafo com as distâncais entre as cidades (caminhos)
  210.     for (int i = 0; i < qt_cidades; i++){
  211.         char linha[21];
  212.         strcpy(linha, cidades[i]);
  213.  
  214.         for(int j = 0; j < qt_cidades; j++){
  215.             char coluna[21];
  216.             strcpy(coluna, cidades[j]);
  217.  
  218.             /// Procura a distâncias entre todas as cidades e preenche todas as
  219.             /// posições da matriz (tanto superior quanto inferior)
  220.             int dist = procura_caminhos_entre_cidades(rotas_ptr, linha, coluna, arestas);
  221.  
  222.             if (grafo[i][j] < dist)
  223.                 grafo[i][j] = dist;
  224.  
  225.             if (grafo[j][i] < dist)
  226.                 grafo[j][i] = dist;
  227.  
  228.         }
  229.     }
  230.  
  231.     /// Identifica a cidade de origem e a cidade de destino por meio de índices.
  232.     /// Esses índices serão passados para a função ShortPath, que já funcionava
  233.     /// de tal maneira
  234.     int origem_index = -1;
  235.     int destino_index = -1;
  236.     for (int i = 0; i < qt_cidades; i++){
  237.         if (strcmp(origem, cidades[i]) == 0){
  238.             origem_index = i;
  239.         }
  240.         if (strcmp(destino, cidades[i]) == 0){
  241.             destino_index = i;
  242.         }
  243.     }
  244.     if (origem_index == -1){
  245.         printf("\n Cidade de origem não encontrada!");
  246.         exit(2);
  247.     }
  248.     if (destino_index == -1){
  249.         printf("\n Cidade de destino não encontrada!");
  250.         exit(3);
  251.     }
  252.     if (origem_index == destino_index){
  253.         printf("Menor percurso:");
  254.         printf(" %s",cidades[origem_index]);
  255.         printf("\nDistancia total: 0 Km\n");
  256.         exit(4);
  257.     }
  258.  
  259.     /// Copia a matriz, deslocando uma unidade para baixo e para a direita
  260.     /// para então passar a matriz copiada para a função ShortPath
  261.  
  262.     int from, to, dist,count, n;
  263.  
  264.  
  265.     int a[MAXNODE][MAXNODE];
  266.     int path[MAXNODE];
  267.  
  268.  
  269.     for (int i = 0; i < qt_cidades; i++){
  270.         for (int j = 0; j < qt_cidades; j++){
  271.             a[i+1][j+1] = grafo[i][j];
  272.         }
  273.     }
  274.  
  275.     /// Chama a função ShortPath e imprime a menor distância
  276.     count = ShortPath(a,qt_cidades,origem_index+1, destino_index+1, path, &dist);
  277.     if(dist){
  278.         printf("Menor percurso:");
  279.         printf(" %s",cidades[origem_index]);
  280.         for(int i=2;i<=count;i++)
  281.             printf(" %s",cidades[path[i]-1]);
  282.         printf("\nDistancia total: %d Km\n", dist);
  283.     }
  284.     else
  285.         printf("\n Path does not exist \n");
  286. }
  287.  
Add Comment
Please, Sign In to add comment