Advertisement
KDOXG

Algoritmo de Dijkstra e Algoritmo Guloso

Apr 9th, 2019
533
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.84 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define bool int
  4. #define dado int
  5.  
  6. typedef struct Nodo {
  7.     dado data;
  8.     //int distance;
  9.     //int index1;
  10.     //int index2;
  11. } Nodo;
  12.  
  13. typedef struct Aresta {
  14.     Nodo *nodoSource, *nodoFinal;
  15.     bool flag_valid;
  16.     int value;
  17. } Aresta;
  18.  
  19. void initializeMatriz(Aresta **aresta, int tam)
  20. {
  21.     int i, j;
  22.     for (i=0; i<tam; i++)
  23.     {
  24.         for (j=0; j<tam; j++)
  25.         {
  26.             aresta[i][j].flag_valid = 0;
  27.             aresta[i][j].nodoSource = NULL;
  28.             aresta[i][j].nodoFinal = NULL;
  29.             aresta[i][j].value = 0;
  30.         }
  31.     }
  32. }
  33.  
  34. void initializeNodo(Nodo *nodo, int i)
  35. {
  36.     //nodo->distance = 2000000000;
  37.     //nodo->index1 = 0;
  38.     //nodo->index2 = 0;
  39.     nodo->data = i;
  40. }
  41.  
  42. bool addNodo(Aresta **aresta, int i, int tam)
  43. {
  44.     int j;
  45.     Nodo *aux;
  46.     if (aresta[i][0].nodoSource != NULL)
  47.     {
  48.         printf("Erro: o nodo ja existe! Reiniciando...");
  49.         return 0;
  50.     }
  51.  
  52.     aux = malloc(sizeof(Nodo));
  53.     if (aux == NULL)
  54.     {
  55.         printf("Erro: o nodo nao pode ser alocado! Reiniciando...");
  56.         return 0;
  57.     }
  58.     initializeNodo(aux, i);
  59.     for (j=0; j<tam; j++)
  60.     {
  61.         aresta[i][j].nodoSource = aux;
  62.         aresta[j][i].nodoFinal = aux;
  63.     }
  64.     return 1;
  65. }
  66.  
  67. void addAresta(Aresta **aresta, int i, int j, int peso)
  68. {
  69.     if (aresta[i][0].nodoSource == NULL || aresta[j][0].nodoSource == NULL)
  70.     {
  71.         printf("Erro: um dos nodos nao existe! Reiniciando...");
  72.         return;
  73.     }
  74.     if (aresta[i][j].flag_valid == 1)
  75.     {
  76.         printf("Erro: ja existe uma aresta! Reiniciando...");
  77.         return;
  78.     }
  79.     if (i == j)
  80.         aresta[i][j].value = 0;
  81.     else
  82.         aresta[i][j].value = peso;
  83.     aresta[i][j].flag_valid = 1;
  84.     return;
  85. }
  86.  
  87. void searchDijkstra(Aresta **aresta, int origem, int destino, int tam)
  88. {
  89.  
  90.     int i, k=-1, aux1, aux2 = 2000000000, valor[tam], vetor[tam], anterior[tam];
  91.     for (i=0; i<tam; i++)
  92.     {
  93.         if (aresta[origem][i].flag_valid == 1)
  94.         {
  95.             anterior[i] = origem;
  96.             valor[i] = aresta[origem][i].value;
  97.         }
  98.         else
  99.         {
  100.             anterior[i] = 0;
  101.             valor[i] = aux2;
  102.         }
  103.         vetor[i]=0;
  104.     }
  105.     vetor[origem] = 1;
  106.     valor[origem] = 0;
  107.  
  108.     do
  109.     {
  110.         aux1 = aux2;
  111.         for (i=0; i<tam; i++)
  112.         {
  113.             if (!vetor[i])
  114.             {
  115.                 if (valor[i] >= 0 && valor[i] < aux1)
  116.                 {
  117.                     aux1 = valor[i];
  118.                     k = i;
  119.                 }
  120.             }
  121.         }
  122.  
  123.         if (aux1 != aux2 && k != destino)
  124.         {
  125.             vetor[k] = 1;
  126.             for (i=0; i<tam; i++)
  127.             {
  128.                 if (!vetor[i])
  129.                 {
  130.                     if (aresta[k][i].flag_valid == 1 && valor[k]+aresta[k][i].value < valor[i])
  131.                     {
  132.                         valor[i] = valor[k] + aresta[k][i].value;
  133.                         anterior[i] = k;
  134.                     }
  135.                 }
  136.             }
  137.         }
  138.     }
  139.     while (k != destino && aux1 != aux2);
  140.  
  141.     if (aux1 == aux2)
  142.     {
  143.         printf("Erro: nao existe caminho entre os nodos %d e %d", origem, destino);
  144.         return;
  145.     }
  146.  
  147.     printf("O caminho mais curto e: ");
  148.     i = destino;
  149.     printf("%d", i);
  150.     i = anterior[i];
  151.     while (i != 0)
  152.     {
  153.         printf("<-%d", i);
  154.         i = anterior[i];
  155.     }
  156.     printf("\nO custo deste caminho e: %d\n", valor[destino]);
  157. }
  158.  
  159. void searchGuloso(Aresta **aresta, int origem, int destino, int tam)
  160. {
  161.     int i, k, aux1, aux2 = 2000000000, valor[tam], vetor[tam], anterior[tam];
  162.  
  163.     for (i=0; i<tam; i++)
  164.     {
  165.         if (aresta[origem][i].flag_valid == 1)
  166.         {
  167.             anterior[i] = origem;
  168.             valor[i] = aresta[origem][i].value;
  169.         }
  170.         else
  171.         {
  172.             anterior[i] = 0;
  173.             valor[i] = aux2;
  174.         }
  175.         vetor[i]=0;
  176.     }
  177.     vetor[origem] = 1;
  178.     valor[origem] = 0;
  179.  
  180.     do
  181.     {
  182.         aux1 = aux2;
  183.         for (i=0; i<tam; i++)
  184.         {
  185.             if (!vetor[i])
  186.             {
  187.                 if (valor[i] >= 0 && valor[i] < aux1)
  188.                 {
  189.                     aux1 = valor[i];
  190.                     k = i;
  191.                 }
  192.             }
  193.         }
  194.  
  195.         if (aux1 != aux2 && k != destino)
  196.         {
  197.             vetor[k] = 1;
  198.             for (i=0; i<tam; i++)
  199.             {
  200.                 if (!vetor[i])
  201.                 {
  202.                     if (aresta[k][i].flag_valid == 1 && valor[i] < aresta[k][i].value)
  203.                     {
  204.                         valor[i] = valor[k] + aresta[k][i].value;
  205.                         anterior[i] = k;
  206.                     }
  207.                 }
  208.             }
  209.         }
  210.  
  211.     }
  212.     while (k != destino && aux1 != aux2);
  213.  
  214.     if (aux1 == aux2)
  215.     {
  216.         printf("Erro: nao existe caminho entre os nodos %d e %d", origem, destino);
  217.         return;
  218.     }
  219.  
  220.     printf("O caminho mais rapido e: ");
  221.     i = destino;
  222.     printf("%d", i);
  223.     i = anterior[i];
  224.     while (i != 0)
  225.     {
  226.         printf("<-%d", i);
  227.         i = anterior[i];
  228.     }
  229.     printf("\nO custo deste caminho e: %d\n", valor[destino]);
  230. }
  231.  
  232. void main()
  233. {
  234.     int i, j, select, tam, nodo_count=0;
  235.     Redo: printf("Digite a quantidade de nodos a armazenar: ");
  236.     do{
  237.         scanf("%d", &tam);
  238.     }while(tam <= 0 || tam > 20);
  239.     Aresta **aresta = malloc(tam*sizeof(Aresta*));
  240.     for (i=0; i<tam; i++)
  241.         aresta[i] = malloc(tam*sizeof(Aresta));
  242.     initializeMatriz(aresta, tam);
  243.     printf("\n\n");
  244.  
  245.     //--------- Testes prĂ©-prontos
  246.     /*
  247.     if(!addNodo(aresta,1,tam)){aresta=aresta;}
  248.     if(!addNodo(aresta,2,tam)){aresta=aresta;}
  249.     if(!addNodo(aresta,3,tam)){aresta=aresta;}
  250.     addAresta(aresta,1,2,8);
  251.     addAresta(aresta,2,3,2);
  252.     addAresta(aresta,1,3,11);
  253.    
  254.     searchDijkstra(aresta,1,3,tam);
  255.     printf("\n\n");
  256.     searchGuloso(aresta,1,3,tam);
  257.     printf("\n\n");
  258.     */
  259.  
  260.     Do: printf("\n\nEscolha... \n1 para adicionar um nodo\n2 para adicionar uma aresta\n3 para buscar o caminho mais curto entre dois nodos\n4 para buscar o caminho mais barato entre dois nodos\n5 para refazer a matriz\n6 para sair\nDigite: ");
  261.     scanf("%d", &select);
  262.     switch(select)
  263.     {
  264.         case 1:
  265.             if (nodo_count == tam)
  266.             {
  267.                 printf("Erro: a capacidade de nodos ja foi alcancada! Reiniciando...");
  268.                 goto Do;
  269.             }
  270.             printf("Digite o indice do nodo: ");
  271.             scanf("%d", &i);
  272.             if (i < 0 || i >= tam)
  273.             {
  274.                 printf("Erro: indice invalido! Reiniciando...");
  275.                 goto Do;
  276.             }
  277.             if (addNodo(aresta,i,tam))
  278.                 nodo_count++;
  279.             goto Do;
  280.         break;
  281.  
  282.         case 2:
  283.             if (nodo_count < 2)
  284.             {
  285.                 printf("Erro: existem menos que 2 nodos. Reiniciando...");
  286.                 goto Do;
  287.             }
  288.             printf("Digite o indice do nodo origem e o indice do nodo destino: ");
  289.             scanf("%d%d", &i, &j);
  290.             if (i < 0 || j < 0 || i >= tam || j >= tam)
  291.             {
  292.                 printf("Erro: indices invalidos! Reiniciando...");
  293.                 goto Do;
  294.             }
  295.  
  296.             printf("Digite o peso da aresta: ");
  297.             scanf("%d", &select);
  298.             if (select <= 0)
  299.             {
  300.                 printf("Erro: o peso nao deve ser negativo! Reiniciando...");
  301.                 goto Do;
  302.             }
  303.             addAresta(aresta,i,j,select);
  304.             goto Do;
  305.         break;
  306.  
  307.         case 3:
  308.             if (nodo_count < 2)
  309.             {
  310.                 printf("Erro: existem menos que 2 nodos! Reiniciando...");
  311.                 goto Do;
  312.             }
  313.             printf("Digite o indice do nodo origem e o indice do nodo destino: ");
  314.             scanf("%d%d", &i, &j);
  315.             if (i < 0 || j < 0 || i >= tam || j >= tam)
  316.             {
  317.                 printf("Erro: indices invalidos! Reiniciando...");
  318.                 goto Do;
  319.             }
  320.  
  321.             searchDijkstra(aresta,i,j,tam);
  322.             goto Do;
  323.         break;
  324.  
  325.         case 4:
  326.             if (nodo_count < 2)
  327.             {
  328.                 printf("Erro: existem menos que 2 nodos! Reiniciando...");
  329.                 goto Do;
  330.             }
  331.             printf("Digite o indice do nodo origem e o indice do nodo destino: ");
  332.             scanf("%d%d", &i, &j);
  333.             if (i < 0 || j < 0 || i >= tam || j >= tam)
  334.             {
  335.                 printf("Erro: indices invalidos! Reiniciando...");
  336.                 goto Do;
  337.             }
  338.  
  339.             searchGuloso(aresta,i,j,tam);
  340.             goto Do;
  341.         break;
  342.  
  343.         case 5:
  344.             for (i=0; aresta[i][0].nodoSource == NULL; i++)
  345.                 if (i == tam-1)
  346.                     goto Next;
  347.             free(aresta[i][0].nodoSource);
  348.  
  349.             for (j=0; j<tam; j++)
  350.             {
  351.                 if (aresta[i][j].nodoFinal != NULL)
  352.                     free(aresta[i][j].nodoFinal);
  353.             }
  354.             Next: for (i=0; i<tam; i++)
  355.                 free(aresta[i]);
  356.             free(aresta);
  357.             printf("\n\n\n------------------------\n\n");
  358.             goto Redo;
  359.         break;
  360.  
  361.         case 6:
  362.             for (i=0; aresta[i][0].nodoSource == NULL; i++)
  363.                 if (i == tam-1)
  364.                     goto Finish;
  365.             free(aresta[i][0].nodoSource);
  366.  
  367.             for (j=0; j<tam; j++)
  368.             {
  369.                 if (aresta[i][j].nodoFinal != NULL)
  370.                     free(aresta[i][j].nodoFinal);
  371.             }
  372.             Finish: for (i=0; i<tam; i++)
  373.                 free(aresta[i]);
  374.             free(aresta);
  375.             exit(1);
  376.         break;
  377.  
  378.         default:
  379.             goto Do;
  380.         break;
  381.     }
  382. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement