Last active
March 5, 2024 22:03
-
-
Save johnnyferreiradev/ade523141cd79e0a494fb808176bed8b to your computer and use it in GitHub Desktop.
Implementação da Solução (Força Bruta) do Problema do Caixeiro Viajante em JavaScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Implementação em JavaScript por Johnny Ferreira (https://gist.github.com/johnnyferreiradevweb/) | |
* baseado na implementação de BárbaraGCOL (https://github.com/BarbaraGCOL) | |
*/ | |
/* Um campo do vetor que contera a melhor rota */ | |
function Rota() { | |
var cidade1, cidade2, custo; | |
} | |
function PCVOtimo() { | |
/* | |
* Verifica se a permutação passada como parâmetro tem custo melhor que o custo | |
* já obtido. Caso positivo, então monta a rota correspondente à permutação como | |
* sendo a melhor rota (e armazena no vetor melhorRota, retornando tambem o custo | |
* total da melhor rota | |
*/ | |
const melhorCaminho = (Grafo, refPMCMR, permutacao) => { | |
var cid1, cid2, custo | |
const proxDaRota = new Array(refPMCMR.melhorRota.length); // Sequencia de cidades de uma rota. Indice = cidade; Valor = prox. da rota | |
// Monta uma rota com a permutação. A primeira cidade é a 0 | |
cid1 = 0 | |
cid2 = permutacao[1] | |
custo = Grafo[cid1][cid2] | |
proxDaRota[cid1] = cid2 | |
for (let j = 2; j < refPMCMR.melhorRota.length; j++) { | |
cid1 = cid2 | |
cid2 = permutacao[j] | |
custo += Grafo[cid1][cid2] | |
proxDaRota[cid1] = cid2 | |
} | |
// Retorno a cidade inicial e fim do cliclo da viajem | |
proxDaRota[cid2] = 0 | |
custo += Grafo[cid2][0] // Custo total | |
// Busca o menor custo e guarda a melhor rota | |
if (custo < refPMCMR.melhorCusto) { | |
refPMCMR.melhorCusto = custo | |
cid2 = 0 | |
for (let k = 0; k < refPMCMR.melhorRota.length; k++) { | |
cid1 = cid2 | |
cid2 = proxDaRota[cid1] | |
refPMCMR.melhorRota[k].cidade1 = cid1 | |
refPMCMR.melhorRota[k].cidade2 = cid2 | |
refPMCMR.melhorRota[k].custo = Grafo[cid1][cid2] | |
} | |
} | |
} | |
/* | |
* Gera os possiveis caminhos entre a cidade zero e as outras (N-1) envolvidas | |
* na busca, armazenando-os no vetor permutacao, um por vez, e a cada permutacao | |
* gerada, chama a funcao melhorCaminho que escolhe o caminho (a permutacao) de | |
* menor custo. | |
*/ | |
const permuta = (permutacao, Grafo, refPMCMR, controle, k) => { | |
var i | |
permutacao[k] = ++controle | |
if (controle == (refPMCMR.melhorRota.length - 1)) { | |
melhorCaminho(Grafo, refPMCMR, permutacao) | |
} else { | |
for (i = 1; i < refPMCMR.melhorRota.length; i++) { | |
if (permutacao[i] == 0) { | |
permuta(permutacao, Grafo, refPMCMR, controle, i) | |
} | |
} | |
} | |
controle-- | |
permutacao[k] = 0 | |
} | |
/* | |
* Gera os possiveis caminhos entre a cidade zero e todas as outras envolvidas | |
* na rota da viagem do caixeiro e escolhe a melhor rota entre todas. | |
*/ | |
this.geraEscolheCaminhos = (Grafo, refPMCMR) => { | |
var controle = -1 | |
refPMCMR.melhorCusto = Infinity | |
for (let i = 0; i < refPMCMR.melhorRota.length; i++) { | |
refPMCMR.melhorRota[i] = new Rota(); | |
} | |
permuta(refPMCMR.permutacao, Grafo, refPMCMR, controle, 1) | |
} | |
// Imprime o resultado da operação | |
this.imprimeMelhorCaminho = (refPMCMR) => { | |
console.log('\nCusto minimo para a viajem do caixeiro: ' + refPMCMR.melhorCusto) | |
console.log('melhor caminho para a viajem do caixeiro:\n') | |
console.log('--- De ------ P/ ------ Custo') | |
for (let i = 0; i < refPMCMR.melhorRota.length; i++) { | |
console.log(`--- ${refPMCMR.melhorRota[i].cidade1} ------- ${refPMCMR.melhorRota[i].cidade2} ------- ${refPMCMR.melhorRota[i].custo}`) | |
} | |
} | |
} | |
// Recebe uma matriz de pesos que representa um grafo não direcionado | |
function start(Grafo) { | |
var numCidades = Grafo.length | |
var melhorCusto | |
const caixeiro = new PCVOtimo | |
const permutacao = new Array(numCidades) | |
const melhorRota = new Array(numCidades) | |
/* @refPMCMR: | |
* Objeto utilizado para passar as variaveis permutacao, melhorCusto | |
* e melhorRota por referencia | |
*/ | |
const refPMCMR = { | |
permutacao, | |
melhorCusto, | |
melhorRota | |
} | |
// Inicializa todos os valores de permutação com 0. | |
// (Em js, um vetor que não foi inicializado retorna undefined em todas os indices) | |
for (let i = 0; i < refPMCMR.permutacao.length; i++) { | |
refPMCMR.permutacao[i] = 0 | |
} | |
caixeiro.geraEscolheCaminhos(Grafo, refPMCMR) | |
caixeiro.imprimeMelhorCaminho(refPMCMR) | |
} | |
// Os indices i e j representam os vertices. Ja os valores v[i][j], representam o custo entre estes vertices. | |
const Grafo = [ | |
[0, 5, 3, 8], | |
[5, 0, 2, 1], | |
[3, 2, 0, 1], | |
[8, 1, 1, 0], | |
]; | |
start(Grafo); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment