Maison > Questions et réponses > le corps du texte
P粉2327937652023-09-04 00:28:48
J'ai pu résoudre le problème en suivant les suggestions d'InSync dans les commentaires
Dans la fonction bfs(), oldpath est utilisé pour stocker le chemin parcouru par chaque nœud (nœud parent), et le chemin le plus court est utilisé pour stocker le résultat
const oldpath = new Map(); let shortestPath = [];
while (queue.length > 0) { let airport = queue.shift(); // mutates the queue const destinations = adjacencyList.get(airport); for (const destination of destinations) { // destination -> origin if (destination === 'BKK') { console.log(`BFS found Bangkok!`) oldpath.set(destination, airport) // remember parentNode retracePath(airport); // loops through all parentNodes of BKK // and adds them to the path console.log(shortestPath); shortestPath = [] } if (!visited.has(destination)) { oldpath.set(destination, airport) // remember parentNode visited.add(destination); queue.push(destination); } } } }
La fonction de la nouvelle fonction est très simple. Ajoutez le nœud parent au chemin le plus court, puis recherchez le nœud parent du nœud parent (s'il existe), et la boucle se termine lorsque le nœud parent actuel est le nœud racine
function retracePath(parentNode){ while(oldpath.get(parentNode)){ // keep going until reaching the root shortestPath.unshift(parentNode); // adding each parent to the path parentNode = oldpath.get(parentNode); // find the parent's parent } }
P粉2141766392023-09-04 00:24:58
Au lieu de marquer un nœud comme visité, profitez de cette opportunité pour marquer le nœud avec son parent. Vous pouvez utiliser une carte pour :
Je recommande également d'éviter de référencer des variables globales dans les fonctions et de passer plutôt tout le nécessaire en paramètres :
function createGraph(airports, routes) { // Your code, but as a function // The graph const adjacencyList = new Map(); // Add node function addNode(airport) { adjacencyList.set(airport, []); } // Add edge, undirected function addEdge(origin, destination) { adjacencyList.get(origin).push(destination); adjacencyList.get(destination).push(origin); } // Create the Graph airports.forEach(addNode); // loop through each route and spread the values into addEdge function routes.forEach(route => addEdge(...route)); return adjacencyList; } function bfs(adjacencyList, start, end) { const cameFrom = new Map(); // Used as linked list, as visited marker, and as queue cameFrom.set(start, null); // As Map maintains insertion order, and keys() is an iterator, // this loop will keep looping as long as new entries are added to it for (const airport of cameFrom.keys()) { for (const destination of adjacencyList.get(airport)) { if (!cameFrom.has(destination)) { cameFrom.set(destination, airport); // remember parentNode if (destination === end) return retracePath(cameFrom, end); } } } } function retracePath(cameFrom, node) { const path = []; while (cameFrom.has(node)) { path.push(node); node = cameFrom.get(node); } return path.reverse(); } const airports = 'PHX BKK OKC JFK LAX MEX EZE HEL LOS LAP LIM'.split(' '); const routes = [ ['PHX', 'LAX'], ['PHX', 'JFK'], ['JFK', 'OKC'], ['JFK', 'HEL'], ['JFK', 'LOS'], ['MEX', 'LAX'], ['MEX', 'BKK'], ['MEX', 'LIM'], ['MEX', 'EZE'], ['LIM', 'BKK'], ]; const adjacencyList = createGraph(airports, routes); const path = bfs(adjacencyList, 'PHX', 'BKK'); console.log(path);