我一直在研究一个小程序,该程序使用OpenMP来计算给定图形中每个顶点的最短路径,以拆分多个线程之间的计算,而不是一次只执行一个顶点。虽然我目前的实现工作,但我想让它能够从格式为“vertex1 vertex2 weight”的文件中读取图形数据,因此图形不会被硬编码到程序中。在OpenMP中实现Dijkstra最短路径算法时可能存在的范围问题?
来源是这里:http://pastebin.com/bkR7QysB
编译如下:
g++ -fopenmp GraphTest.cpp WeightedGraph.cpp -o dijkstra
使用下面的数据作为输入:
foo derp 50
narf balls 30
foo balls 20
balls derp 60
derp narf 40
derp cox 30
foo narf 50
narf pie 99
cox pie 15
cox narf 10
我的输出是:
Enter filename: lol.out
Printing all edges currently in graph:
(foo, derp) : cost 50
(narf, balls) : cost 30
(foo, balls) : cost 20
(balls, derp) : cost 60
(derp, narf) : cost 40
(derp, cox) : cost 30
(foo, narf) : cost 50
(narf, pie) : cost 99
(cox, pie) : cost 15
(cox, narf) : cost 10
[thread:0] Showing single-source shortest path run for source vertex balls. Format is (start, end) : cost.
(balls, balls : cost 0)
(balls, derp : cost 60)
[thread:0] Showing single-source shortest path run for source vertex cox. Format is (start, end) : cost.
(cox, cox : cost 0)
(cox, narf : cost 10)
[thread:1] Showing single-source shortest path run for source vertex derp. Format is (start, end) : cost.
(derp, derp : cost 0)
(derp, cox : cost 30)
[thread:1] Showing single-source shortest path run for source vertex foo. Format is (start, end) : cost.
(foo, foo : cost 0)
(foo, narf : cost 50)
[thread:2] Showing single-source shortest path run for source vertex narf. Format is (start, end) : cost.
(narf, narf : cost 0)
(narf, cox : cost 10)
[thread:2] Showing single-source shortest path run for source vertex pie. Format is (start, end) : cost.
(pie, pie : cost 0)
(pie, cox : cost 15)
这显然是不正确的 - 它应该打印从顶点到图形中每个其他顶点的最短路径,但这里只打印最短路径(它始终为0)和直接到其中一个直接路径相邻的邻居。它根本没有遍历图。最奇怪的一部分,然而,就是取消注释附近GraphTest.cpp的结束和注释掉文件处理代码,这样的图形数据是硬编码到程序块巨大,一切工作正常:
Printing all edges currently in graph:
(foo, derp) : cost 50
(narf, balls) : cost 30
(foo, balls) : cost 20
(balls, derp) : cost 60
(derp, narf) : cost 40
(derp, cox) : cost 30
(foo, narf) : cost 50
(narf, pie) : cost 99
(cox, pie) : cost 15
(cox, narf) : cost 10
[thread:0] Showing single-source shortest path run for source vertex balls. Format is (start, end) : cost.
(balls, balls : cost 0)
(balls, foo : cost 20)
(balls, narf : cost 30)
(balls, cox : cost 40)
(balls, pie : cost 55)
(balls, derp : cost 60)
[thread:0] Showing single-source shortest path run for source vertex cox. Format is (start, end) : cost.
(cox, cox : cost 0)
(cox, narf : cost 10)
(cox, pie : cost 15)
(cox, derp : cost 30)
(cox, balls : cost 40)
(cox, foo : cost 60)
[thread:1] Showing single-source shortest path run for source vertex derp. Format is (start, end) : cost.
(derp, derp : cost 0)
(derp, cox : cost 30)
(derp, narf : cost 40)
(derp, pie : cost 45)
(derp, foo : cost 50)
(derp, balls : cost 60)
[thread:1] Showing single-source shortest path run for source vertex foo. Format is (start, end) : cost.
(foo, foo : cost 0)
(foo, balls : cost 20)
(foo, derp : cost 50)
(foo, narf : cost 50)
(foo, cox : cost 60)
(foo, pie : cost 75)
[thread:2] Showing single-source shortest path run for source vertex narf. Format is (start, end) : cost.
(narf, narf : cost 0)
(narf, cox : cost 10)
(narf, pie : cost 25)
(narf, balls : cost 30)
(narf, derp : cost 40)
(narf, foo : cost 50)
[thread:2] Showing single-source shortest path run for source vertex pie. Format is (start, end) : cost.
(pie, pie : cost 0)
(pie, cox : cost 15)
(pie, narf : cost 25)
(pie, derp : cost 45)
(pie, balls : cost 55)
(pie, foo : cost 75)
我真的不知道这里发生了什么。我能想到的唯一事情就是某个地方过早超出范围,导致我的图形对象行为异常,但如果这是真的,那么这两个输出应该是错的......希望有人比我更聪明,可以运行这并帮助我找出哪里出了问题。
其实,方向并没有真正在这种情况下重要 - 法getDistance的(顶点*,顶点*)不会检查两种方式,所以如果仅定义其中一个,则它会为(v1,v2)和(v2,v1)报告相同的距离。我使用new来代替简单的实例,因为那些真正的DID太快地超出了范围,并且我的代码在整个地方都被隔离,直到我用指针取代它们。 – Cirvante 2011-05-11 01:48:10
编辑:@ dusktreader感谢您的重复插入覆盖前一个元素的提示。我添加了一个快速的.find()== .end()检查来查看要插入的顶点是否已经在地图中,并且似乎解决了这个问题。 :) – Cirvante 2011-05-11 01:50:23