/*************************************************************************** * Função: GRA Inserir aresta ******/ GRA_tpCondRet GRA_InserirAresta(GRA_tppGrafo pGrafoParm, char *nomeAresta, char *nomeVerticeOrigem, char *nomeVerticeDestino) { tpGrafo *pGrafo = (tpGrafo*) pGrafoParm; tpAresta *pAresta; LIS_tpCondRet lisCondRet; GRA_tpCondRet graCondRet; tpVertice *pVerticeOrigem, *pVerticeDestino; if (pGrafo == NULL) { return GRA_CondRetGrafoNaoFoiCriado; } // Procura vértice origem graCondRet = ProcurarVertice(pGrafo, nomeVerticeOrigem, &pVerticeOrigem); if (graCondRet != GRA_CondRetOK) { return graCondRet; } // Procura vértice destino graCondRet = ProcurarVertice(pGrafo, nomeVerticeDestino, &pVerticeDestino); if (graCondRet != GRA_CondRetOK) { return graCondRet; } // Verifica se já existe uma aresta com este nome if (ExisteAresta(pVerticeOrigem, nomeAresta)) { return GRA_CondRetJaExiste; } MEM_Alloc(sizeof(tpAresta), (void **) &pAresta); if (pAresta == NULL) { return GRA_CondRetFaltouMemoria; } // Atualiza os antecessores do vértice destino lisCondRet = LIS_InserirElementoApos(pVerticeDestino->pAntecessores, pVerticeOrigem); if (lisCondRet == LIS_CondRetFaltouMemoria) { return GRA_CondRetFaltouMemoria; } // Atualiza os sucessores do vértice origem lisCondRet = LIS_InserirElementoApos(pVerticeOrigem->pSucessores, pAresta); if (lisCondRet == LIS_CondRetFaltouMemoria) { return GRA_CondRetFaltouMemoria; } pAresta->nome = nomeAresta; pAresta->pVertice = pVerticeDestino; return GRA_CondRetOK; }
//Função que implementa o Algoritmo de Dijkstra e realiza as impressões no arquivo de saida void Dijkstra(TipoGrafo *Grafo, TipoVertice *Raiz, TipoVertice *Destino,int **Dist,FILE *saida){ int *Antecessor,*vetor,kk=0,bond, auxiliar,t, i,j; float tempo,prob=1,Pesao,PESO,dis[9999];//dis armazenará o menor caminho entre cada 2 pontos de vértices char vis[1000];//Será responsável pelo Flag que indica se o vértice já foi visitado ou não Antecessor=(int*)malloc(Grafo->NumVertices*sizeof(int)); vetor=(int*)malloc(Grafo->NumVertices*sizeof(int)); memset (vis, 0, sizeof (vis)); //Processo para preencher a memória alocada pela variável vis com 0 memset (dis, 0x7f, sizeof (dis));//Semelhante ao processo acima, porém para a variável dis dis[*Raiz] = 0;//Setando que a distância entre a Raiz e ela mesmo é 0 Antecessor[*Raiz] = 1;//Setando que a Raiz não tem antecessor. for (t = *Raiz; t < Grafo->NumVertices+*Raiz; t++){ int v = -1; // armazenará o vértice que será analisado/visitado nesta etapa for (i = *Raiz; i < Grafo->NumVertices+*Raiz; i++)// Seleciona o vértice v não visitado (analisado) cuja distância Vi->v seja mínima; por esse vértice ter a menor if (!vis[i] && (v < 0 || dis[i] < dis[v])) // distância dentre todos os outros, garante-se que não existe nenhum caminho que nos permita chegar nele com uma v = i; // distância menor vis[v] = 1; for (i = 0; i < Grafo->NumVertices; i++){ if(Dist[i][1]==FORA){//A Matriz Dist contem todos os vertices do Grafo nas posições Dist[x][0] e suas respectivas flags(se estão dentro de um raio de delegacia) em Dist[x][1] PESO=INFINITO; //Se o vertice está fora do raio de alguma ele recebe disntãncia infinita para não ser percorrido }else{ PESO=ExisteAresta(i,v,Grafo); //Caso ela esteja dentro do raio de alguma delegacia, a aresta entre o vertice em análise e o segundo recebe o peso real. } if (PESO!=0 && dis[i] > dis[v] + PESO){ dis[i] = dis[v] + PESO; //Atualiza a distància até o vertice i; Antecessor[i]=v; // V fica armazenado como vértice antecessor a i neste caso } } } bond=*Destino; while (bond != *Raiz ){//Loop para armazenar o caminho entre o Destino e sua origem vetor[kk]=bond; bond=Antecessor[bond]; kk++; } vetor[kk]=*Raiz; auxiliar=kk; while(kk>0){ Pesao=ExisteAresta(vetor[kk],vetor[kk-1],Grafo);//O Peso entre os vértices do caminho é pego para que seja calculada a probabilidade de não ser assaltado no caminho if(Pesao!=0){ prob=prob*(1-Pesao); }else{ fprintf(saida,"-1");//Irá imprimir no arquivo de saida -1, caso não haja caminho possível entre a origem e o destino } kk--; } prob=(1-prob);//Inversão da Probabilidade, para que está vire a probabilidade de ser assaltado if(Pesao!=0){ fprintf(saida,"%.2f %d",prob,*Raiz);//Imprimi no arquivo de saida a probabilidade ser assaltado e a origem do caminho while(auxiliar>0){ fprintf(saida," %d",vetor[auxiliar-1]);//imprimi os demais vértices do caminho auxiliar--; } } free(vetor);//Libera as memorias alocadas dinâmicamente free(Antecessor);//Libera as memorias alocadas dinâmicamente }
int main(){ FILE *fp; TipoGrafo* grafo; TipoVertice v1, v2; TipoPeso peso; int op, res, num; printf("1- Cria grafo.\n"); printf("2- Insere Aresta.\n"); printf("3- Existe Aresta.\n"); printf("4- Retira Aresta\n"); printf("5- Consulta Aresta\n"); printf("6- Mostra Lista de Adjacentes.\n"); printf("7- Mostra Grafo\n"); printf("8- Libera Grafo\n"); printf("9- Caminho mais curto.\n"); printf("10- Insere Arestas Arquivo.\n"); printf("11- Desativa Estação.\n"); printf("12- Mostrar Estações Desativadas.\n"); printf("13- Caminho mais barato.\n"); printf("0- Sair."); do{ printf("\nEscolha uma opcao:\n"); scanf("%d",&op); switch(op){ case 1:{ printf("\nEscolha o numero de estações:\n"); scanf("%d",&num); grafo = Cria_grafo(num); break; } case 2:{ printf("\nPrimeira estação:\n"); scanf("%d",&v1); printf("\nSegunda estação:\n"); scanf("%d",&v2); printf("\nDistancia:\n"); scanf("%f",&peso.distancia); printf("\nPreco:\n"); scanf("%f",&peso.preco); res = InsereAresta(grafo, v1, v2, peso); if(res == 1){ printf("\nAresta foi inserida.\n"); GravaArestaArquivo(fp, v1, v2, peso); } else{ if(res == 0) printf("\nAresta nao existe.\n"); else printf("\nGrafo nao existe.\n"); } break; } case 3:{ printf("\nEscolha a primeira estação:\n"); scanf("%d",&v1); printf("\nEscolha a segunda estação:\n"); scanf("%d",&v2); res = ExisteAresta(grafo, v1, v2); if(res == 1) printf("\nAresta existe.\n"); else{ if(res == 0) printf("\nAresta nao existe.\n"); else printf("\nGrafo nao existe.\n"); } break; } case 4:{ printf("\nEscolha a primeira estação:\n"); scanf("%d",&v1); printf("\nEscolha a segunda estação:\n"); scanf("%d",&v2); res = RetiraAresta(grafo, v1, v2); if(res == 1) printf("\nAresta foi retirada.\n"); else{ if(res == 0) printf("\nAresta nao existe.\n"); else printf("\nGrafo nao existe.\n"); } break; } case 5:{ printf("\nEscolha a primeira estação:\n"); scanf("%d",&v1); printf("\nEscolha a segunda estação:\n"); scanf("%d",&v2); res = ConsultaAresta(grafo, v1, v2, &peso); if(res == 1) printf("O peso da aresta (%d,%d) = Distancia: %0.2f; Preco: %0.2f\n", v1, v2, peso.distancia, peso.preco); else{ if(res == 0) printf("\nAresta nao existe.\n"); else printf("\nGrafo nao existe.\n"); } break; } case 6:{ printf("\nEscolha a estação:\n"); scanf("%d",&v1); MostraListaAdjacentes(grafo, v1); break; } case 7:{ MostraGrafo(grafo); break; } case 8:{ grafo = LiberaGrafo(grafo); break; } case 9:{ printf("\nEscolha a estação de origem:\n"); scanf("%d",&v1); printf("\nEscolha a estação de destino:\n"); scanf("%d",&v2); Caminho_mais_Curto(grafo, v1, v2); break; } case 10:{ if(InsereArestaArquivo(fp, grafo)) printf("Arestas inseridas"); break; } case 11:{ printf("\nEscolha a estação:\n"); scanf("%d",&v1); res = DesativaVertice(grafo, v1); if(res == 1) printf("Estação %d desativada\n", v1); else{ if(res == 0) printf("\nEstação já estava desativada.\n"); else printf("\nGrafo nao existe.\n"); } break; } case 12:{ VerticesDesativados(grafo); break; } case 13:{ printf("\nEscolha a estação de origem:\n"); scanf("%d",&v1); printf("\nEscolha a estação de destino:\n"); scanf("%d",&v2); Caminho_mais_Barato(grafo, v1, v2); } default: ; } } while(op != 0); return 0; }