【发布时间】:2018-12-23 02:26:11
【问题描述】:
这是一个招聘人员问我的面试问题,问题基本上是计算所有节点到每个节点的最短路径,我的解决方案如下
启动所有可能的边(没有反向 A - B 与 B-A 相同)
每个节点将在下面表示 (src, cost, current_list, dest) ,src 和 dest 基本上是我们之前启动的所有可能的边
地图:
for each edge you traverse, you duplicate your tuple and add the current
traversed node to the cost and current list.
if the node is the destination you annotate finish, if the the node is
in the current list, you annotate delete
减少:
Don't really need to do anything besides outputting finish and deleting
delete and let the other node go through the next round of map
And by outputting I mean for each src, dest pair only output the least cost
招聘人员说这效率不高,我可以看到这效率不高,因为您正在组合遍历,但我能想到的唯一选择是如果您有 n 个节点,然后生成 n 个服务器并为每个节点执行 dijkstra招聘人员说的也是错误的。有人可以帮我解决这个问题吗?
编辑:
例如。三角图
边是 A-B、B-C、C-A,路径成本为 1
算法
- 首先我们启动所有可能的源目标对,记住边缘的反转不是唯一的 A-B、A-C、B-C(省略B-A、C-A、B-C)
对于每个源目标对,我们有以下元组
(src=A, cost=None, current_list=A, dest=B, annotate=continue)
(src=A, cost=None, current_list=A, dest=C, annotate=continue)
(src=B, cost=None, current_list=B, dest=C, annotate=continue)
-
现在我们开始 map reduce 算法
for each tuple in the tuple list we initiate: for each neighbor of the node at the end of current_list if the next neighbor is already in the current_list set annotate = delete elif the next neighbor is the dest set annotate = finish add path cost to cost else duplicate the current node add neighbor to current_list add path cost to cost delete the current tuple
在我们的例子中
(src=A, cost=None, current_list=A, dest=B, annotate=continue)
=>
(src=A, cost=1, current_list=AB, dest=B, annotate=finish)
(src=A, cost=1, current_list=AC, dest=B, annotate=continue)
(src=A, cost=None, current_list=A, dest=C, annotate=continue)
=>
(src=A, cost=1, current_list=AC, dest=C, annotate=finish)
(src=A, cost=1, current_list=AB, dest=C, annotate=continue)
(src=B, cost=None, current_list=B, dest=C, annotate=continue)
=>
(src=B, cost=1, current_list=BC, dest=C, annotate=finish)
(src=B, cost=1, current_list=BA, dest=C, annotate=continue)
-
减少
注意:我们减少了 src、dest 对,并将其用作我们的 key 对于元组列表中的每个元组
if annotate == finish keep trace of min cost and delete tuple for each src dest pair that is not the current min then pass the current min as result elif annotate == delete delete the tuple else pass down to the next round of map 地图
因为我们还有一些元组有 annotate = continue
(src=B, cost=1, current_list=BA, dest=C, annotate=continue)
=>
(src=B, cost=2, current_list=BAC, dest=C, annotate=finish)
(src=B, cost=2, current_list=BAB, dest=C, annotate=delete)
(src=A, cost=1, current_list=AC, dest=B, annotate=continue)
=>
(src=A, cost=2, current_list=ACB, dest=B, annotate=finish)
(src=A, cost=2, current_list=ACA, dest=B, annotate=delete)
(src=A, cost=1, current_list=AB, dest=C, annotate=continue)
=>
(src=A, cost=2, current_list=ABC, dest=C, annotate=finish)
(src=A, cost=2, current_list=ABA, dest=C, annotate=delete)
- 减少
我们没有 continue tuples,现在我们只使用 reduce 来找到每个 src dest 对的最小值
【问题讨论】:
-
你所描述的甚至没有正确解决 MapReduce 的单源最短路径问题,如果我是你的面试官,我首先不会担心效率,而是正确性。跨度>
-
我不确定你的意思,reduce部分只输出成本最低的源节点目标节点对,并且我遍历从A到B的所有可能路径,其中A和B是任意的
-
所以你不想要全对最短路径,而是两个顶点之间的最小成本边?
-
我跟踪最短路径和最小成本边,因为我有一个当前列表变量,我传递,如果成本结果是最小成本,那么当前列表必须是成本方面的最短路径,您可以将当前列表作为链表或数组来跟踪遍历顺序
-
如果我有 n 个节点,我计算了最短路径(如 A->B->C)和每个节点到 n - 1 个其他节点的最小成本(即从顶点到顶点)。我的算法没有计算最小生成树
标签: algorithm graph mapreduce graph-algorithm breadth-first-search