diff --git a/src/c/TravellingSalesman.c b/src/c/TravellingSalesman.c index b7924423..46d435e9 100644 --- a/src/c/TravellingSalesman.c +++ b/src/c/TravellingSalesman.c @@ -1,7 +1,7 @@ /* -* Problema do Caixeiro Viajante em C -* Utilizando uma matriz de distância para representar um grafo não direcionado. -* Objetivo: Encontrar o menor caminho que passe por todos os vértices sem repetir nenhum, e chegar novamente ao vértice de início +* Traveling Salesman Problem in C +* Using a distance matrix to represent an undirected graph. +* Objective: Find the shortest path that visits all vertices without repeating any, and returns to the starting vertex. * * 6 * (4)-----(0) @@ -16,92 +16,87 @@ * | | 3 * -------------- * -* -* Matriz de Distância +* Distance Matrix * 0 1 2 3 4 * 0 0 2 - 3 6 * 1 2 0 4 3 - * 2 - 4 0 7 3 * 3 3 3 7 0 3 * 4 6 - 3 3 0 -* -* */ #include +#include #define VERTICES 5 -#define INFINITO 429496729 - -int tempSolucao[VERTICES]; -int melhorSolucao[VERTICES]; -bool visitados[VERTICES]; -int valorMelhorSolucao = INFINITO; -int valorSolucaoAtual = 0; +#define INFINITY 429496729 -int matriz[VERTICES][VERTICES] = {{ 0, 2, INFINITO, 3, 6 }, - { 2, 0, 4, 3, INFINITO }, - { INFINITO, 4, 0, 7, 3 }, - { 3, 3, 7, 0, 3 }, - { 6, INFINITO, 3, 3, 0 }}; +int tempSolution[VERTICES]; +int bestSolution[VERTICES]; +bool visited[VERTICES]; +int bestSolutionValue = INFINITY; +int currentSolutionValue = 0; -void caixeiroViajanteAux(int x){ - // Se o valor da solução atual já estiver maior que o valor da melhor solução já para, pois já não pode mais ser a melhor solução - if( valorSolucaoAtual > valorMelhorSolucao ) - return; +int matrix[VERTICES][VERTICES] = {{ 0, 2, INFINITY, 3, 6 }, + { 2, 0, 4, 3, INFINITY }, + { INFINITY, 4, 0, 7, 3 }, + { 3, 3, 7, 0, 3 }, + { 6, INFINITY, 3, 3, 0 }}; - if( x == VERTICES ){ // Se x == VERTICES significa que o vetor da solução temporária está completo - int distancia = matriz[tempSolucao[x-1]][tempSolucao[0]]; - // Se encontrou uma solução melhor/menor - if( distancia < INFINITO && valorSolucaoAtual + distancia < valorMelhorSolucao ){ - valorMelhorSolucao = valorSolucaoAtual + distancia; // Substitui a melhor solução pela melhor encontrada agora - // Copia todo o vetor de solução temporária para o vetor de melhor solução encontrada - for (int i = 0; i < VERTICES; ++i){ - melhorSolucao[i] = tempSolucao[i]; - } - } - return; - } +void travelingSalesmanAux(int x) { + // If the current solution value is already greater than the best solution, stop as it can't be the best solution + if (currentSolutionValue > bestSolutionValue) + return; - int ultimo = tempSolucao[x-1]; // Ultimo recebe o número do último vértice que se encontra na solução temporária - // For que percorre todas as colunas da matriz na linha do último vértice do vetor solução temporária - for (int i = 0; i < VERTICES; i++){ - // Se a posição i do vetor ainda não foi visitada, e se o valor da matriz na posição é menor que INFINITO - if( visitados[i] == false && matriz[ultimo][i] < INFINITO ){ - visitados[i] = true; // Marca como visitado - tempSolucao[x] = i; // Carrega o vértice que está passando no vetor de solução temporária - valorSolucaoAtual += matriz[ultimo][i]; // Incrementa o valor da matriz na variável que guarda o total do caminho percorrido - caixeiroViajanteAux(x+1); // Chama recursivamente para o próximo vértice - valorSolucaoAtual -= matriz[ultimo][i]; // Se ainda não terminou, diminuí o valor da váriavel que guarda o total da solução atual - visitados[i] = false; // Seta como false a posição para poder ser utilizado por outro vértice - } - - } + if (x == VERTICES) { // If x == VERTICES, it means the temporary solution array is complete + int distance = matrix[tempSolution[x-1]][tempSolution[0]]; + // If a better (shorter) solution is found + if (distance < INFINITY && currentSolutionValue + distance < bestSolutionValue) { + bestSolutionValue = currentSolutionValue + distance; // Update the best solution with the new better one + // Copy the entire temporary solution array to the best solution array + for (int i = 0; i < VERTICES; ++i) { + bestSolution[i] = tempSolution[i]; + } + } + return; + } + int last = tempSolution[x-1]; // 'last' holds the number of the last vertex in the temporary solution array + // Loop through all columns in the matrix on the row of the last vertex in the temporary solution array + for (int i = 0; i < VERTICES; i++) { + // If the i-th vertex hasn't been visited, and the matrix value is less than INFINITY + if (!visited[i] && matrix[last][i] < INFINITY) { + visited[i] = true; // Mark as visited + tempSolution[x] = i; // Add the current vertex to the temporary solution array + currentSolutionValue += matrix[last][i]; // Increment the path total + travelingSalesmanAux(x + 1); // Recursively call for the next vertex + currentSolutionValue -= matrix[last][i]; // Decrease the path total if not finished yet + visited[i] = false; // Mark the vertex as unvisited so it can be used again by another vertex + } + } } -void caixeiroViajante(int inicial){ - visitados[inicial] = true; // Marca o primeiro vértice como visitado (0) - tempSolucao[0] = inicial; // Coloca o vértice 0 na primeira posição do vetor de solução temporária - caixeiroViajanteAux(1); // Chama o método auxiliar do caixeiro viajante +void travelingSalesman(int start) { + visited[start] = true; // Mark the starting vertex as visited (0) + tempSolution[0] = start; // Place vertex 0 in the first position of the temporary solution array + travelingSalesmanAux(1); // Call the auxiliary function for the traveling salesman problem } -void iniciaVetores(){ - for (int i = 0; i < VERTICES; i++){ - visitados[i] = false; - tempSolucao[i] = -1; - melhorSolucao[i] = -1; - } +void initializeArrays() { + for (int i = 0; i < VERTICES; i++) { + visited[i] = false; + tempSolution[i] = -1; + bestSolution[i] = -1; + } } -int main(){ - - iniciaVetores(); - caixeiroViajante(0); +int main() { + initializeArrays(); + travelingSalesman(0); - printf("Caminho mínimo: %d\n", valorMelhorSolucao); - for (int i = 0; i < VERTICES; i++){ - printf("%d, ", melhorSolucao[i]); - } - printf("\n\n"); -} \ No newline at end of file + printf("Minimum path cost: %d\n", bestSolutionValue); + for (int i = 0; i < VERTICES; i++) { + printf("%d, ", bestSolution[i]); + } + printf("\n\n"); +}