Kimossab

ED - Ficha Grafos V1

May 29th, 2016
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.63 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5.  
  6. typedef struct grafo
  7. {
  8.     int N, N2;
  9.     int NRamos;
  10.     int *Matriz; // Vai ter N*N casas
  11. }Grafo;
  12.  
  13. typedef struct no
  14. {
  15.     int Info;
  16.     struct no *Next;
  17. }NO;
  18. typedef struct lista_int
  19. {
  20.     NO *Inicio;
  21.     int Nelementos;
  22. }Lista_Int;
  23.  
  24. //---------------------------------------------------
  25. void wait(int mlseconds)
  26. {
  27.     clock_t endwait;
  28.     endwait = clock() + mlseconds;
  29.     while(clock() < endwait) {}
  30. }
  31. //---------------------------------------------------
  32. void spaces(int n)
  33. {
  34.     int i;
  35.  
  36.     for(i = 0; i < n; i++)
  37.         printf("   ");
  38.     return;
  39. }
  40.  
  41. Grafo *CriarGrafo(int nl)
  42. {
  43.     Grafo *G = (Grafo *)malloc(sizeof(Grafo));
  44.     G->N = nl;
  45.     G->N2 = nl*nl;
  46.     G->NRamos = 0;
  47.     G->Matriz = (int *)malloc(sizeof(int)*nl*nl);
  48.     return G;
  49. }
  50.  
  51. void DestruirGrafo(Grafo *G)
  52. {
  53.     if(!G)
  54.         return;
  55.     free(G->Matriz);
  56.     free(G);
  57. }
  58.  
  59. Grafo *PreencherGrafo(char *nficheiro)
  60. {
  61.     Grafo *res = NULL;
  62.     FILE *f = fopen(nficheiro, "r");
  63.     char buffer[200];
  64.     int nos;
  65.  
  66.     if(f)
  67.     {
  68.         fscanf(f, "%d", &nos);
  69.         res = CriarGrafo(nos);
  70.         for(int i=0; i < res->N2; i++)
  71.             fscanf(f, "%d", &res->Matriz[i]);
  72.     }
  73.     fclose(f);
  74.     return res;
  75. }
  76. /** \brief MostrarGrafo: Fun??o que permite visualizar os dados de um grafo no ecran
  77. * \param G : Grafo
  78. * \return void
  79. */
  80. void MostrarGrafo(Grafo *G)
  81. {
  82.     printf("\n");
  83.     if(!G)
  84.         return;
  85.     for(int i=0; i < G->N; i++)
  86.     {
  87.         for(int n=0; n < G->N; n++)
  88.         {
  89.             printf("%d", G->Matriz[i*G->N + n]);
  90.             spaces(1);
  91.             if(n >= i && G->Matriz[i*G->N + n] != 0)
  92.                 G->NRamos++;
  93.         }
  94.         printf("\n");
  95.     }
  96.     printf("\n");
  97. }
  98. /** \brief DensidadeGrafo: Densidade de um Grafo
  99. *
  100. * \param G : Grafo
  101. * \return void
  102. */
  103. void DensidadeGrafo(Grafo *G)
  104. {
  105.     if(!G)
  106.         return;
  107.     printf("\nA densidade do grafo é: %f\n\n", 2 * G->NRamos / G->N);
  108. }
  109. /** \brief GrauGrafo : Grau de um Grafo: ? o maior n?mero de liga??es de um n?
  110. *
  111. * \param G : Grafo
  112. * \return void
  113. *
  114. */
  115. void GrauGrafo(Grafo *G)
  116. {
  117.     if(!G)
  118.         return;
  119.  
  120.     int nlig;
  121.     int max=0;
  122.  
  123.     for(int i=0; i < G->N; i++)
  124.     {
  125.         nlig=0;
  126.         for(int n=i; n < G->N; n++)
  127.             if(G->Matriz[i*G->N + n] != 0)
  128.                 nlig++;
  129.         if(nlig > max)
  130.             max = nlig;
  131.     }
  132.     printf("\nO grau do grafo e: %d", max);
  133. }
  134.  
  135. /** \brief GravarFicheiroRAM
  136. *
  137. * \param nficheiro : Nome do ficheiro a gravar
  138. * \param  G : Grafo
  139. * \return void
  140. *
  141. */
  142. void GravarFicheiroRAM(char *nficheiro, Grafo *G)
  143. {
  144.     if(!G)
  145.         return;
  146.  
  147.     FILE *f = fopen(nficheiro, "w");
  148.     fprintf(f, "%d\n", G->N);
  149.     fprintf(f, "%d\n", G->NRamos);
  150.     for(int i=0; i < G->N; i++)
  151.         for(int n=i; n < G->N; n++)
  152.             if(G->Matriz[i*G->N + n] != 0)
  153.                 fprintf(f, "%d %d %d\n", i, n, G->Matriz[i*G->N + n]);
  154.  
  155.     fclose(f);
  156. }
  157.  
  158. /** \brief AdicionarArcoGrafo: Dados dois Nos e o custo, faz a liga??o entre os n?s
  159. *
  160. * \param G Grafo*
  161. * \return void
  162. *
  163. */
  164. void AdicionarArcoGrafo(Grafo *G)
  165. {
  166.     int n1, n2, c;
  167.     printf("\nInsira o numero dos nos que quer ligar: ");
  168.     scanf("%d %d", &n1, &n2);
  169.     printf("\nInsira o custo da ligcao: ");
  170.     scanf("%d", &c);
  171.  
  172.     if(G->Matriz[n1 * G->N + n2] != 0)
  173.         printf("\nArco ja existente!");
  174.     else
  175.         G->Matriz[n1 *G->N + n2] = G->Matriz[n2 * G->N + n1] = c;
  176. }
  177.  
  178. /** \brief RemoverArcoGrafo: Dados dois Nos remove a liga??o entre os n?s
  179. *
  180. * \param G Grafo*
  181. * \return void
  182. *
  183. */
  184. void RemoverArcoGrafo(Grafo *G)
  185. {
  186.     int n1, n2;
  187.     printf("\nInsira o numero dos nos que quer remover a ligacao: ");
  188.     scanf("%d %d", &n1, &n2);
  189.  
  190.     if(G->Matriz[n1 * G->N + n2] == 0)
  191.         printf("\nArco inexistente!");
  192.     else
  193.         G->Matriz[n1 *G->N + n2] = G->Matriz[n2 * G->N + n1] = 0;
  194. }
  195.  
  196.  
  197. void ListaAddVal(Lista_Int *L, int v)
  198. {
  199.     if(!L)
  200.         return;
  201.     NO *novo = (NO *)malloc(sizeof(NO));
  202.     novo->Info = v;
  203.     novo->Next = NULL;
  204.     NO *n = L->Inicio;
  205.     if(!n)
  206.     {
  207.         L->Inicio =novo;
  208.         L->Nelementos++;
  209.     }
  210.     else
  211.     {
  212.         while(n->Next)
  213.             n = n->Next;
  214.         n->Next = novo;
  215.         L->Nelementos++;
  216.     }
  217. }
  218.  
  219. Lista_Int *copylist(Lista_Int *L)
  220. {
  221.     Lista_Int *NL = (Lista_Int*)malloc(sizeof(Lista_Int));
  222.     NL->Inicio = NULL;
  223.     NL->Nelementos = 0;
  224.     NO *a = L->Inicio;
  225.     while(a)
  226.     {
  227.         ListaAddVal(NL, a->Info);
  228.         a=a->Next;
  229.     }
  230.     return NL;
  231. }
  232.  
  233. bool isinlist(Lista_Int *L, int v)
  234. {
  235.     if(!L)
  236.         return false;
  237.     NO *n = L->Inicio;
  238.     while(n)
  239.     {
  240.         if(n->Info == v)
  241.             return true;
  242.         n=n->Next;
  243.     }
  244.     return false;
  245. }
  246.  
  247. void DestruirLista(Lista_Int *L)
  248. {
  249.     if(!L)
  250.         return;
  251.     NO *n = L->Inicio;
  252.     NO *a;
  253.     while(n)
  254.     {
  255.         a = n->Next;
  256.         free(n);
  257.         n = a;
  258.     }
  259.     free(L);
  260. }
  261.  
  262. int IrCaminho(Grafo *G, int ni, int nf, Lista_Int **LHistorico, int *custo)
  263. {
  264.     ListaAddVal(*LHistorico, ni);
  265.     if(ni == nf)
  266.         return 1;
  267.  
  268.     Lista_Int *aux = NULL;
  269.     int maxcusto=0;
  270.     int c;
  271.     for(int i=0; i < G->N; i++)
  272.     {
  273.         if(!isinlist(*LHistorico, i) && G->Matriz[ni *G->N + i] != 0)
  274.         {
  275.             Lista_Int *Copy = copylist(*LHistorico);
  276.  
  277.             c = *custo + G->Matriz[ni *G->N + i];
  278.  
  279.             if(IrCaminho(G, i, nf, &Copy, &c) == 1 && aux == NULL || c < maxcusto)
  280.             {
  281.                 DestruirLista(aux);
  282.                 maxcusto = c;
  283.                 aux = Copy;
  284.             }
  285.             else
  286.                 DestruirLista(Copy);
  287.         }
  288.     }
  289.     if(aux != NULL)
  290.     {
  291.         *LHistorico = aux;
  292.         *custo = maxcusto;
  293.         return 1;
  294.     }
  295.     return 0;
  296. }
  297. int IrTodosCaminhos(Grafo *G, int ni, int nf, Lista_Int **LHistorico, int *custo)
  298. {
  299.     ListaAddVal(*LHistorico, ni);
  300.     if(ni == nf)
  301.     {
  302.         NO *a = (*LHistorico)->Inicio;
  303.         while(a)
  304.         {
  305.             printf("%d > ", a->Info);
  306.             a=a->Next;
  307.         }
  308.         printf("\n");
  309.         return 1;
  310.     }
  311.  
  312.     Lista_Int *aux = NULL;
  313.     int maxcusto=0;
  314.     int c;
  315.     for(int i=0; i < G->N; i++)
  316.     {
  317.         if(!isinlist(*LHistorico, i) && G->Matriz[ni *G->N + i] != 0)
  318.         {
  319.             Lista_Int *Copy = copylist(*LHistorico);
  320.  
  321.             c = *custo + G->Matriz[ni *G->N + i];
  322.  
  323.             if(IrTodosCaminhos(G, i, nf, &Copy, &c) == 1 && aux == NULL || c < maxcusto)
  324.             {
  325.                 DestruirLista(aux);
  326.                 maxcusto = c;
  327.                 aux = Copy;
  328.             }
  329.             else
  330.                 DestruirLista(Copy);
  331.         }
  332.     }
  333.     if(aux != NULL)
  334.     {
  335.         *LHistorico = aux;
  336.         *custo = maxcusto;
  337.         return 1;
  338.     }
  339.     return 0;
  340. }
  341. /** \brief ConetividadeEntreNosGrafo : Calcula o caminho entre 2 n?s, invocando a Fun??o IrCaminho
  342. *
  343. * \param G Grafo*
  344. * \return void
  345. *
  346. */
  347. void ConetividadeEntreNosGrafo(Grafo *G)
  348. {
  349.     int n1, n2;
  350.     printf("Insira os nos que quer ligar: ");
  351.     scanf("%d %d", &n1, &n2);
  352.     Lista_Int *cam = (Lista_Int *)malloc(sizeof(Lista_Int));
  353.     cam->Inicio = NULL;
  354.     cam->Nelementos =0;
  355.     int custo = 0;
  356.     if(IrCaminho(G, n1, n2, &cam, &custo) == 1)
  357.     {
  358.         printf("Caminho encontrado:\n");
  359.         NO *n = cam->Inicio;
  360.         while(n)
  361.         {
  362.             printf("%d > ", n->Info);
  363.             n=n->Next;
  364.         }
  365.         printf("\nCom custo de %d\n", custo);
  366.         DestruirLista(cam);
  367.     }
  368.     else
  369.         printf("Caminho nao encontrado\n");
  370. }
  371.  
  372. /** \brief TodosCaminhosEntreNosGrafo : Fun??o que pede os 2 caminhos em quest?o e invoca o algoritmo
  373. *                                      IrTodosCaminho
  374. * \param G Grafo*
  375. * \return void
  376. *
  377. */
  378. void TodosCaminhosEntreNosGrafo(Grafo *G)
  379. {
  380.     int n1, n2;
  381.     printf("Insira os nos que quer ligar: ");
  382.     scanf("%d %d", &n1, &n2);
  383.     Lista_Int *cam = (Lista_Int *)malloc(sizeof(Lista_Int));
  384.     cam->Inicio = NULL;
  385.     cam->Nelementos =0;
  386.     int custo = 0;
  387.     IrTodosCaminhos(G, n1, n2, &cam, &custo);
  388.     DestruirLista(cam);
  389. }
  390.  
  391. /** \brief Menu :
  392. *
  393. * \return int
  394. *
  395. */
  396. int Menu()
  397. {
  398.     printf("1 - Ler Grafo de Ficheiro \n");
  399.     printf("2 - Mostrar Grafo \n");
  400.     printf("3 - Densidade de um Grafo \n");
  401.     printf("4 - Grau de um Grafo \n");
  402.     printf("5 - Gravar Grafo em Ficheiro RAM\n");
  403.     printf("6 - Destruir Grafo\n");
  404.     printf("7 - Adicionar Caminho entre 2 nos\n");
  405.     printf("8 - Remover Caminho entre 2 nos\n");
  406.     printf("9 - Conectividade entre 2 nos e o seu Custo\n");
  407.     printf("10 - Todos Caminhos Possiveis entre 2 nos com todos os Custos\n");
  408.     printf("0 - Sair\n");
  409.     int opcao;
  410.     printf("Qual a OPCAO ? : ");
  411.     scanf(" %d", &opcao);
  412.     return opcao;
  413. }
  414.  
  415.  
  416. /** \brief Main : Programa principal
  417. *
  418. * \param argc int
  419. * \param argv[] char*
  420. * \return int
  421. *
  422. */
  423. int main(int argc, char *argv[])
  424. {
  425.     printf("Inicio Parte 1\n \n");
  426.  
  427.     char Ficheiro[50];
  428.     //sprintf(Ficheiro, "%s", "Dados\\grafo6");
  429.     sprintf(Ficheiro, "%s", "grafo.txt");
  430.  
  431.     Grafo *G = NULL;
  432.     G = PreencherGrafo(Ficheiro);
  433.     int Opcao;
  434.     do
  435.     {
  436.         Opcao = Menu();
  437.         switch(Opcao)
  438.         {
  439.             case 1: DestruirGrafo(G);
  440.                 G = PreencherGrafo(Ficheiro);
  441.                 break;
  442.             case 2: MostrarGrafo(G); break;
  443.             case 3: DensidadeGrafo(G); break;
  444.             case 4: GrauGrafo(G); break;
  445.             case 5: GravarFicheiroRAM(Ficheiro, G); break;
  446.             case 6: DestruirGrafo(G); G = NULL; break;
  447.             case 7: AdicionarArcoGrafo(G); break;
  448.             case 8: RemoverArcoGrafo(G); break;
  449.             case 9: ConetividadeEntreNosGrafo(G); break;
  450.             case 10: TodosCaminhosEntreNosGrafo(G); break;
  451.         };
  452.     } while(Opcao != 0);
  453.     DestruirGrafo(G);
  454.     printf("\nFim \n \n");
  455.     return 0;
  456. }
Advertisement
Add Comment
Please, Sign In to add comment