Pii*_*kaa 2 javascript graph-theory javascript-objects
我怎样才能得到这个结果:
[
{Paris,Amsterdam,Berlin},
{Paris,Bruxelles,Amsterdam,Berlin},
{Paris,Bruxelles,Berlin}
]
Run Code Online (Sandbox Code Playgroud)
从这个数组:
[
{ HD: '9:20', V1: 'Paris', V2: 'Amsterdam', D: '3:20' },
{ HD: '8:30', V1: 'Paris', V2: 'Bruxelles', D: '1:20' },
{ HD: '10:00', V1: 'Bruxelles', V2: 'Amsterdam', D: '2:10' },
{ HD: '12:30', V1: 'Amsterdam', V2: 'Berlin', D: '6:10' },
{ HD: '11:30', V1: 'Bruxelles', V2: 'Berlin', D: '9:20' }
]
Run Code Online (Sandbox Code Playgroud)
我想从这个数组映射数据,以获得从一个城市到另一个城市的路径的所有可能性,例如从“巴黎”到“柏林”。
+-----------------------+
| |
| v
Paris -> Bruxelles -> Amsterdam -> Berlin
| ^
| |
+-----------------------+
Run Code Online (Sandbox Code Playgroud)
我们可以建立与映射到它们的可能的目的地的阵列,其是更方便比输入对象来使用,然后运行源字符串对象DFS在图形上和得到每个结果的路径。
function *findPaths(graph, src, dst, path=[]) {
if (src === dst) {
yield path.concat(dst);
}
else if (graph[src]) {
path.push(src);
for (const neighbor of graph[src]) {
yield *findPaths(graph, neighbor, dst, path, visited);
}
path.pop(src);
}
};
const graphify = routes => {
const graph = {};
for (const node of routes) {
if (!graph[node.V1]) {
graph[node.V1] = [];
}
graph[node.V1].push(node.V2)
}
return graph;
};
const routes = [
{ HD: '9:20', V1: 'Paris', V2: 'Amsterdam', D: '3:20' },
{ HD: '8:30', V1: 'Paris', V2: 'Bruxelles', D: '1:20' },
{ HD: '10:00', V1: 'Bruxelles', V2: 'Amsterdam', D: '2:10' },
{ HD: '12:30', V1: 'Amsterdam', V2: 'Berlin', D: '6:10' },
{ HD: '11:30', V1: 'Bruxelles', V2: 'Berlin', D: '9:20' }
];
console.log(...findPaths(graphify(routes), "Paris", "Berlin"));Run Code Online (Sandbox Code Playgroud)
如果您预计图形中存在循环,请添加一个Set以跟踪访问过的节点,以避免在遍历期间重新访问它们:
function *findPaths(graph, src, dst, path=[], visited=(new Set())) {
if (src === dst) {
yield path.concat(dst);
}
else if (graph[src] && !visited.has(src)) {
visited.add(src);
path.push(src);
for (const neighbor of graph[src]) {
yield *findPaths(graph, neighbor, dst, path, visited);
}
visited.delete(src);
path.pop(src);
}
};
const graphify = routes => {
const graph = {};
for (const node of routes) {
if (!graph[node.V1]) {
graph[node.V1] = [];
}
graph[node.V1].push(node.V2)
}
return graph;
};
const routes = [
{ HD: '9:20', V1: 'Paris', V2: 'Amsterdam', D: '3:20' },
{ HD: '8:30', V1: 'Paris', V2: 'Bruxelles', D: '1:20' },
{ HD: '10:00', V1: 'Bruxelles', V2: 'Amsterdam', D: '2:10' },
{ HD: '12:30', V1: 'Amsterdam', V2: 'Paris', D: '6:10' },
{ HD: '12:30', V1: 'Amsterdam', V2: 'Berlin', D: '6:10' },
{ HD: '11:30', V1: 'Bruxelles', V2: 'Berlin', D: '9:20' },
{ HD: '11:30', V1: 'Bruxelles', V2: 'Paris', D: '9:20' }
];
console.log(...findPaths(graphify(routes), "Paris", "Berlin"));Run Code Online (Sandbox Code Playgroud)
如果您想考虑旅行时间(边权重),请使用Dijkstra 算法。实现更复杂,因为我们需要一个优先级队列(最小/斐波那契堆)来有效地提取最短的暂定距离。