- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我和我的同事正在讨论 Dijkstra 算法的实现。这是使用 Python 的实现:
def dijkstra(self, origin, destination):
"""Use Dijkstra's algorithm to find the cheapest path."""
routes = Heap()
for neighbor in self.neighbors(origin):
price = self.get_price(origin, neighbor)
routes.push(Route(price=price, path=[origin, neighbor]))
visited = set()
visited.add(origin)
while routes:
# Find the nearest yet-to-visit airport
price, path = routes.pop()
airport = path[-1]
if airport in visited:
continue
# We have arrived! Wo-hoo!
if airport is destination:
return price, path
# Tentative distances to all the unvisited neighbors
for neighbor in self.neighbors(airport):
if neighbor not in visited:
# Total spent so far plus the price of getting there
new_price = price + self.get_price(airport, neighbor)
new_path = path + [neighbor]
routes.push(Route(new_price, new_path))
visited.add(airport)
return float('infinity')
这里有争议的是:
if neighbor not in visited:
我的观点是,这一行必须替换成类似的东西
if neighbor not in visited or new_price < cost_so_far[neighbor]
在我发现的算法的所有实现中,您必须检查到达成本低于节点当前成本的节点时的情况。例如,来自 Wikipedia 的此伪代码的第 17 和 18 行 :
1 function Dijkstra(Graph, source):
2 dist[source] ← 0 // Initialization
3
4 create vertex set Q
5
6 for each vertex v in Graph:
7 if v ≠ source
8 dist[v] ← INFINITY // Unknown distance from source to v
9 prev[v] ← UNDEFINED // Predecessor of v
10
11 Q.add_with_priority(v, dist[v])
12
13
14 while Q is not empty: // The main loop
15 u ← Q.extract_min() // Remove and return best vertex
16 for each neighbor v of u: // only v that is still in Q
17 alt = dist[u] + length(u, v)
18 if alt < dist[v]
19 dist[v] ← alt
20 prev[v] ← u
21 Q.decrease_priority(v, alt)
22
23 return dist[], prev[]
问题是:我同事的实现是否正确,或者是否应该修改代码以检查您是否以低于当前价格的价格到达某个邻居?
注意:这里是source code我同事的实现情况。
最佳答案
所以,问题是你的代码中的行是否
if neighbor not in visited:
可以或必须替换为
if neighbor not in visited or new_price < cost_so_far[neighbor]:
答案是:可以,可以;必须,不。添加new_price < cost_so_far[neighbor]
不会改变算法流程中的任何内容,每次都是错误的 neighbor not in visited
是假的。
原因在于 Dijkstra 算法的工作原理。本质上,它构建了一棵最短路径树。每当 airport
添加到 visited
, 它被认为在树中:此时,算法已经找到了到这个 airport
的最短路径。 .
假设在步骤x
,我们添加某个机场A
至 visited
.进一步假设在步骤y > x
, cost_so_far
去机场A
减少。怎么会减少呢?这需要一些 new_price = price + self.get_price(airport, neighbor)
小于 price
在步骤y
.现在回想一下 routes
是一个优先队列,所以它提供 price
s 非降序排列。图的边也是非负的(否则,Dijkstra算法确实会产生错误的结果,不适用)。所以,我们得出一个矛盾:新的 new_price
至少是旧的价格,但结果却比那个低。
混淆的根源可能是实现的主循环逐一考虑了一些路由。本质上,这些路线对应于图的边。所以,可以有 |E|路线,但只有 |V|他们中的一个将被接受,所有其他人将无法满足条件 if airport in visited: continue
.如果我们实现该算法,使得主循环的每次迭代恰好添加一个 airport
至 visited
(正好是最短路径树的一个顶点),整个事情可能会变得更加清晰。
关于python - 使用 Dijkstra 算法时是否必须检查多次访问的节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34912351/
我有一个 if 语句,如下所示 if (not(fullpath.lower().endswith(".pdf")) or not (fullpath.lower().endswith(tup
然而,在 PHP 中,可以: only appears if $foo is true. only appears if $foo is false. 在 Javascript 中,能否在一个脚
XML有很多好处。它既是机器可读的,也是人类可读的,它具有标准化的格式,并且用途广泛。 它也有一些缺点。它是冗长的,不是传输大量数据的非常有效的方法。 XML最有用的方面之一是模式语言。使用模式,您可
由于长期使用 SQL2000,我并没有真正深入了解公用表表达式。 我给出的答案here (#4025380)和 here (#4018793)违背了潮流,因为他们没有使用 CTE。 我很欣赏它们对于递
我有一个应用程序: void deleteObj(id){ MyObj obj = getObjById(id); if (obj == null) { throw n
我的代码如下。可能我以类似的方式多次使用它,即简单地说,我正在以这种方式管理 session 和事务: List users= null; try{ sess
在开发J2EE Web应用程序时,我通常会按以下方式组织我的包结构 com.jameselsey.. 控制器-控制器/操作转到此处 服务-事务服务类,由控制器调用 域-应用程序使用的我的域类/对象 D
这更多是出于好奇而不是任何重要问题,但我只是想知道 memmove 中的以下片段文档: Copying takes place as if an intermediate buffer were us
路径压缩涉及将根指定为路径上每个节点的新父节点——这可能会降低根的等级,并可能降低路径上所有节点的等级。有办法解决这个问题吗?有必要处理这个吗?或者,也许可以将等级视为树高的上限而不是确切的高度? 谢
我有两个类,A 和 B。A 是 B 的父类,我有一个函数接收指向 A 类型类的指针,检查它是否也是 B 类型,如果是将调用另一个函数,该函数接受一个指向类型 B 的类的指针。当函数调用另一个函数时,我
有没有办法让 valgrind 使用多个处理器? 我正在使用 valgrind 的 callgrind 进行一些瓶颈分析,并注意到我的应用程序中的资源使用行为与在 valgrind/callgrind
假设我们要使用 ReaderT [(a,b)]超过 Maybe monad,然后我们想在列表中进行查找。 现在,一个简单且不常见的方法是: 第一种可能性 find a = ReaderT (looku
我的代码似乎有问题。我需要说的是: if ( $('html').attr('lang').val() == 'fr-FR' ) { // do this } else { // do
根据this文章(2018 年 4 月)AKS 在可用性集中运行时能够跨故障域智能放置 Pod,但尚不考虑更新域。很快就会使用更新域将 Pod 放入 AKS 中吗? 最佳答案 当您设置集群时,它已经自
course | section | type comart2 : bsit201 : lec comart2 :
我正在开发自己的 SDK,而这又依赖于某些第 3 方 SDK。例如 - OkHttp。 我应该将 OkHttp 添加到我的 build.gradle 中,还是让我的 SDK 用户包含它?在这种情况下,
随着 Rust 越来越充实,我对它的兴趣开始激起。我喜欢它支持代数数据类型,尤其是那些匹配的事实,但是对其他功能习语有什么想法吗? 例如标准库中是否有标准过滤器/映射/归约函数的集合,更重要的是,您能
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 9 年前。 Improve
我一直在研究 PHP 中的对象。我见过的所有示例甚至在它们自己的对象上都使用了对象构造函数。 PHP 会强制您这样做吗?如果是,为什么? 例如: firstname = $firstname;
...比关联数组? 关联数组会占用更多内存吗? $arr = array(1, 1, 1); $arr[10] = 1; $arr[] = 1; // <- index is 11; does the
我是一名优秀的程序员,十分优秀!