JavaScript 算法:以最小成本从有向图中打印出路径

问题描述

这是一个问题,可以使用每条边上具有不同成本的有向图进行建模。

我们的输入是一个边数组。

const edges = [['A','B',20],['B','C',10],['A',50],'D',5],['D',2]]

['A', 表示从 AB 的成本是 20。我想编写一个函数,返回给定地点到另一个成本最低的地点之间的路径。请注意,此图中没有循环

在这种情况下,如果起点是A,目的地是C,那么有三种方式可以去

path 1: A => C - cost 50
path 2: A => B => C - cost 30
path 3: A => B => D => C - cost 27

所以函数应该返回具有最小成本的路径,即 A,B,D,C

这是我的尝试:

function bar(edges,start,end) {
    const paths = []
    const visited = new Map()
    const graph = edges.reduce((map,[start,end,cost]) => {
        if(map.has(start)) {
            map.get(start).push([end,cost])
        } else {
            map.set(start,[[end,cost]])
        }
        return map
    },new Map())
    const queue = [[start,0]]
    for(const [node,costSofar] of queue) {
        if(node === end) {
            let pointer = node
            const path = []
            while(pointer) {
                path.push(pointer)
                pointer = visited.get(pointer)
            }    
            
            paths.push([path.reverse().join(','),costSofar])
            continue
        }
        graph.get(node).forEach(([dest,localCost]) => {
            // this part ? is problematic
            visited.set(dest,node)
            queue.push([dest,localCost + costSofar])
            
        })
    }

    return paths.sort(([pathA,costA],[pathB,costB]) => costA - costB)[0]
}

所以我使用邻接表来表示图,即

{
    A: [['B',['C',50]]
    B: [['C',5]]
    D: [['C',2]]
}

然后我使用广度优先搜索来探索图形并记录路径,一旦我们到达目的地,我们将路径添加到 paths。顺便说一句,我知道 Dijkstra 算法,但是,如果我错了,请纠正我,我觉得因为这个图没有循环,所以我们可以使用普通的 bfs 来解决它。

我的问题是,我的函数实际上有一个错误,虽然它确实捕获了所有具有相应成本的路径,但路径并非 100% 正确。如果您注销函数的 return 语句,即 paths.sort(([pathA,costB]) => costA - costB),您将看到此处的值为  [ [ 'A,C',27 ],[ 'A,30 ],50 ] ]  。前两个是正确的,但最后一个应该是 ['A',50]。我认为问题是由填充 visited 地图的方式引起的,但我不知道如何解决该问题。

解决方法

因为您希望为每条可能的路径维护单独的路径信息,即使一条路径稍后拦截另一条路径,具有 visited 映射(其中键是目标节点)不会起作用,因为 {{1} } 会覆盖之前路径的信息。

最后我没有使用 visited.set 在循环中获取指针,而是在迭代时获取 visited Map 的节点信息。递归会有所帮助。

graph

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...