草庐IT

c++ - 用于 GPS 系统的 Dijkstra 算法的更快替代方案

coder 2024-02-11 原文

如果涉及到算法,以及我为游戏制作的插件,我是一个真正的速度狂。

速度是..有点..不满意。尤其是当你驾车四处行驶并且你没有按照你的路径行驶时,必须重新计算路径..这需要一些时间,所以游戏中的 GPS 正在叠加许多“错误的方向”信号(并叠加信号意味着以后要进行更多的计算,对于每一个错误的移动方式)因为我想要一个快速的实时 gps 系统,它会不断更新。

我将旧算法(一些简单的 dijkstra 实现)更改为 boost::dijkstra 来计算从节点 A 到节点 B 的路径

(总节点列表大约有 15k 个节点和 40k 个连接,对于好奇的人,这里是 map :http://gz.pxf24.pl/downloads/prv2.jpg(12 MB),红线中的边是节点),

但它并没有真正提高速度。 (至少不明显,可能是 50 毫秒)。

Node数组中存储的信息是:

The ID of the Node,
The position of the node,
All the connections to the node (and which way it is connected to the other nodes, TO, FROM, or BOTH)
Distance to the connected nodes.

我很好奇是否有人知道 C/C++ 中一些更快的替代方案? 任何建议(+代码示例?)表示赞赏!


如果有人对该项目感兴趣,请看这里(源代码+二进制文件):

https://gpb.googlecode.com/files/RouteConnector_177.zip

在此视频中,您可以看到 gps 系统是什么样的:

http://www.youtu.be/xsIhArstyU8

如您所见,红色路线更新缓慢(好吧,对于我们 - 游戏玩家 - 它很慢)。

( ByTheWay: 红线之间的缝隙早就修好了 :p )

最佳答案

既然是GPS,肯定有固定的目的地。您不必在每次更改当前节点时都计算从当前节点到目的地的路径,而是可以找到从目的地到所有节点的最短路径:只需从目的地开始运行一次 Dijkstra。这将花费与现在更新一样长的时间。

然后,在每个节点中,prev = 到此节点的最短路径上的前一个节点(从您的目的地)。在计算最短路径时更新它。或者您可以在节点外使用 prev[] 数组 - 基本上,无论您使用什么方法重建路径,现在都应该仍然有效。

移动汽车时,路径由 currentNode.prev -> currentNode.prev.prev -> ... 给出。

这将解决更新滞后问题并使您的路径保持最佳状态,但您在进入目的地时仍然会有轻微的滞后。

即使您计划使用 A* 或其他并不总能给出最佳答案的启发式方法,您也应该考虑这种方法,至少在您仍然落后于这些方法的情况下。

例如,如果您有此图表:

1 - 2 cost 3
1 - 3 cost 4
2 - 4 cost 1
3 - 4 cost 2
3 - 5 cost 5

prev 数组看起来像这样(在计算距离 d[] 时计算):

       1 2 3 4 5
prev = 1 1 1 2 3

含义:

shortest path FROM TO 
                 1  2 = prev[2], 2 = 1, 3
                 1  3 = prev[3], 3 = 1, 3
                 1  4 = prev[ prev[4] ], prev[4], 4 = 1, 2, 4 (fill in right to left)
                 1  5 = prev[ prev[5] ], prev[5], 5 = 1, 3, 5 
                 etc.

关于c++ - 用于 GPS 系统的 Dijkstra 算法的更快替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11277993/

有关c++ - 用于 GPS 系统的 Dijkstra 算法的更快替代方案的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  4. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  5. ruby-on-rails - 更好的替代方法 try( :output). try( :data). try( :name)? - 2

    “输出”是一个序列化的OpenStruct。定义标题try(:output).try(:data).try(:title)结束什么会更好?:) 最佳答案 或者只是这样:deftitleoutput.data.titlerescuenilend 关于ruby-on-rails-更好的替代方法try(:output).try(:data).try(:name)?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c

  6. ruby - inverse_of 是否适用于 has_many? - 2

    当我使用has_one时,它​​工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290

  7. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  8. 区块链之加解密算法&数字证书 - 2

    目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非

  9. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  10. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

随机推荐