Untitled
unknown
javascript
2 years ago
3.4 kB
4
Indexable
// https://levelup.gitconnected.com/finding-the-shortest-path-in-javascript-dijkstras-algorithm-8d16451eea34 // https://github.com/noamsauerutley/shortest-path/blob/master/test/shortestPath.spec.js // Решение вот этого графа // https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Shortest_path_with_direct_weights.svg/800px-Shortest_path_with_direct_weights.svg.png const shortestDistanceNode = (distances, visited) => { let shortest = null; for (let node in distances) { let currentIsShortest = shortest === null || distances[node] < distances[shortest]; if (currentIsShortest && !visited.includes(node)) { shortest = node; } } return shortest; }; const findShortestPath = (graph, startNode, endNode) => { // establish object for recording distances from the start node let distances = {}; distances[endNode] = "Infinity"; distances = Object.assign(distances, graph[startNode]); // track paths let parents = { endNode: null }; for (let child in graph[startNode]) { parents[child] = startNode; } // track nodes that have already been visited let visited = []; // find the nearest node let node = shortestDistanceNode(distances, visited); // for that node while (node) { // find its distance from the start node & its child nodes let distance = distances[node]; let children = graph[node]; // for each of those child nodes for (let child in children) { // make sure each child node is not the start node if (String(child) === String(startNode)) { continue; } else { // save the distance from the start node to the child node let newdistance = distance + children[child]; // if there's no recorded distance from the start node to the child node in the distances object // or if the recorded distance is shorter than the previously stored distance from the start node to the child node // save the distance to the object // record the path if (!distances[child] || distances[child] > newdistance) { distances[child] = newdistance; parents[child] = node; } } } // move the node to the visited set visited.push(node); // move to the nearest neighbor node node = shortestDistanceNode(distances, visited); } // using the stored paths from start node to end node // record the shortest path let shortestPath = [endNode]; let parent = parents[endNode]; while (parent) { shortestPath.push(parent); parent = parents[parent]; } shortestPath.reverse(); // return the shortest path from start node to end node & its distance let results = { distance: distances[endNode], path: shortestPath, }; return results; }; // module.exports = findShortestPath; // const graph = { // start: { A: 5, B: 2 }, // A: { start: 1, C: 4, D: 2 }, // B: { A: 8, D: 7 }, // C: { D: 6, end: 3 }, // D: { end: 1 }, // end: {}, // }; // 0 = start // 1 = A // 2 = B // 3 = end const graph = { A: {B: 4, C: 2 }, B: {C: 5, D: 10}, C: {E: 3}, E: {D: 4}, D: {F: 11}, }; const shortestPath = findShortestPath(graph, 'A', 'F'); console.log(shortestPath); // test(`shortest path from 'start' to 'end' should be 8 with start-A-D-end`, () => { // const shortestPath = findShortestPath(graph, 'start', 'end'); // expect(shortestPath).toEqual({ // distance: 8, // path: ['start', 'A', 'D', 'end'], // }); // });
Editor is loading...