c++ - Boost Graph - 大图上非常慢的 Astar
问题描述
目前我的寻路系统遇到了一些问题,在我的大图上“异常”缓慢:
我的图表
- 图属性:16814 个顶点/61512 个边
- 图是有向的。
- 每个顶点都有一个子图ID(岛ID)→子图之间没有解决方案,但总是在同一个子图中。
图的每个顶点定义为:
- 类型(岩石、沙子、...)。
- 高度
最后一条规则,地球没有连接到海洋(所以我们有很多子图)。
我的 Astar 配置
我的启发式方法非常经典:我计算当前顶点位置和目标位置之间的点。
我没有预先计算边缘的权重。我使用“复杂”算法(取决于步行者的速度,地面类型,如果我们上升或下降)
float PathWorld::updateWeight(const Agent& agent, const EdgeInfo& edgeInfo) const
{
const Agent::Navigation& navigation = agent.getNavigation();
const auto& fromTerrain = edgeInfo._from->_terrain;
const auto& toTerrain = edgeInfo._to->_terrain;
const float mean = (navigation._speed.at(fromTerrain._type) + navigation._speed.at(toTerrain._type)) * 0.5f;
const float diff = BT::Maths::clamp((1000.0f + toTerrain._height - fromTerrain._height) / 1000.0f, 0.5f, 2.0f);
return edgeInfo._distance / mean * diff;
}
问题
目前,当我计算一条路径时,执行时间不到 1 毫秒到 1 秒。路径解决方案只是在 8 或 80 个顶点之间,我没有成比例的时间。(因此 8 个顶点路径可能需要 1 秒,而 80 个顶点路径需要 1 毫秒)。
我使用 Visual Studio 进行了快速分析:提升是我的瓶颈。
代码和测试数据
所有完整的代码和测试数据都可以在我的 GitHub 上找到。
https://github.com/Rominitch/myBlogSource/tree/master/DEMO/TestPathfinding
简单/小型演示不会遇到我的问题。只是复杂的情况。所有图表均由同一程序生成(未发布)。
我的测试程序输出
我的测试程序真的很假: - 我将一个节点开始到我的图表中 - 在此之后我取 XXX 个节点(使用索引)并计算路径。
输出:
Statistics:
Start node: Ocean H= 0 SubGraph= 2
nbValid: 2053/15000 (valid path / number of path computed)
min / max: 1/75 (number of vertex in path computed)
min time for one path: 0 ms
max time for one path: 7 ms
Statistics:
Start node: Forest H= 100 SubGraph= 1
nbValid: 1420/1500
min / max: 1/76
min time for one path: 0 ms
max time for one path: 558 ms
Statistics:
Start node: Swamp H= 50 SubGraph= 1
nbValid: 601/1000
min / max: 1/51
min time for one path: 0 ms
max time for one path: 1246 ms
Statistics:
Start node: Clay H= 300 SubGraph= 22
nbValid: 138/15000
min / max: 1/12
min time for one path: 0 ms
max time for one path: 0 ms
问题
- 我的问题在哪里?(使用不良提升/不良图表/提升限制)
- Boost 是解决寻路的好选择(另一个库)?
- 我们可以优化我的图形数据(最佳提升算法,减少数据重复,...)?
谢谢 !
解决方案
行 !我发现了我的问题。
目前,Bug 在我的启发式实现中,它不计算当前节点和目标之间距离的平方。它只是做一个“准随机”的启发式。
此外,就我而言
boost::astar_search
性能不如
boost::astar_search_tree
最后,我也优化了我的图表(删除虚拟边)。
新统计:
Statistics:
Start node: Ocean H= 0 SubGraph= 2
nbValid: 2028/15000
min / max: 1/145
min time for one path: 0 ms
max time for one path: 13 ms
mean: 0 ms
Global time: 1845 ms
Statistics:
Start node: Forest H= 100 SubGraph= 1
nbValid: 1420/1500
min / max: 1/92
min time for one path: 0 ms
max time for one path: 13 ms
mean: 0 ms
Global time: 1232 ms
Statistics:
Start node: Swamp H= 50 SubGraph= 1
nbValid: 601/1000
min / max: 1/50
min time for one path: 0 ms
max time for one path: 11 ms
mean: 0 ms
Global time: 504 ms
Statistics:
Start node: Clay H= 300 SubGraph= 23
nbValid: 138/15000
min / max: 1/17
min time for one path: 0 ms
max time for one path: 1 ms
mean: 0 ms
Global time: 115 ms
推荐阅读
- java - 将 UTC 中的 ISO 8601 字符串转换为本地时间 - JodaTime 正在添加与本地时区相反的时间
- dictionary - 来自另一个源文件的 TCL 字典
- html - 视频上传 HTML5 未按预期上传到我的页面
- android-room - INSERT query type is not supported yet. You can use:SELECT, DELETE, UPDATE
- c# - 增强并行操作 C#
- java - 返回一个新的 MenuItems ArrayList,其中仅包含当前可用的那些菜单项
- ios - 如何从 iOS 上的照片输出中检索 AVCameraCalibrationData?
- flutter - 流构建器的 Flutter DropdownMenuItem 问题
- c# - C# JSON 我无法反序列化双精度数。我得到“不是一个有效的整数错误”
- javascript - 如何更新 FullCalendar 中的事件