起点和终点固定的多目的地最短路线
Multi-destination shortest route with fixed start and destination
这个问题已经以类似的方式被问了好几次,但我发现的现有答案都对我没有实际帮助。
问题:我有一个固定的起点,一个固定目的地,以及介于两者之间的许多目的地。从所需的起点开始,我想计算沿着所有目的地行进并在给定目的地结束的最短可能路线。
对于我必须解决的特定问题,我需要一个非常快速的解决方案。我在想Floyd-Warshall算法是否合适,据我所知,我的问题与所有对的最短路径问题有关。
然而,我不知道这些将如何与我所拥有的数据相结合(每条路线可能有数百个中间目的地,可以在智能手机上计算)。
我也在想,如果这可以转化为一个经典的TSP问题(再次),那么我可以使用协和式TSP库,据说它具有出色的性能。
所以:你能给我推荐一个解决我问题的最佳方案吗?同时也推荐一些C++代码给我一个开始吗?
您有一个固定的、不同的端点这一事实并没有让问题变得更容易。如果我们能找到一个多项式时间算法来解决这个问题,我们可以简单地将每个节点设置为终点,解决所有这些问题,找到最佳解决方案(通过将成本加回到每个节点的起点),我们就有了一个解决(经典)TSP问题的多项式时间算法。
允许您多次访问节点似乎不会让问题变得更容易。而对于形式证明,需要将TSP减少到这个程度(而不是相反),当将任意两个节点之间的边缘代价设置为这两个节点间的最短路径时,请考虑。当你做到这一点时,你将不得不基本上解决TSP问题——这个TSP问题的最优解应该是原始问题的最优解法。
虽然简单地使用最短路径偶尔可能会导致不必要的节点重复,但对于最优解决方案来说,情况并非如此,因为在通过最短路径隐式访问重复节点之前,首先访问重复节点总是会降低成本。
要使用TSP求解器解决此问题,请考虑将每两个节点之间的边的权重设置为等于这两个节点间的最短路径,并添加一条从终点到起点的路径,成本为0。
如果使用你正在使用的解算器无法做到这一点,维基百科列出了一些你可以遵循的方法。
性能说明:
是的,我建议运行一个全对最短路径算法来获得上面的最短路径。
请注意,即使是TSP的(体面的)近似算法也应该比解决所有对最短路径问题花费很多的时间,因此首先这样做的相对开销应该最小。
如果你相信可以使用所有对的最短路径来解决这个问题(但我不认为可以),那就改为这样做吧——它会更快。
您试图解决的问题是n-p complete
和TSP(Travelling Salesman Problem)
可以简化为它,TSP也是n-p完全的。但是您可以比蛮力解决这个问题做得更好,这是通过使用Held-Karp
为TSP给出的动态规划算法来解决的,该算法在O(2^N)
中进行了轻微的修改,远远优于蛮力O(N!)
。但它也有类似的空间复杂性。如果你这样做是为了实际应用,那么你当然可以使用启发式算法,比如遗传算法、蚁群优化,它们给出了很好的解决方案,虽然不能证明是最优的,但非常接近。
我不建议将此问题转换为Traveling Salesman。这将对解决方案提出额外的要求,比如你只能访问每个中间目的地一次,根据你的描述,这不是一个要求。更重要的是,TSP是NP难的,而全对最短路径问题可以在多项式时间内求解。
如果这确实是全对最短路径问题,你最好的选择可能是使用Floyd-Warshall算法或Johnson算法,这两种算法都可以在多项式时间内解决问题。
如果这个问题实际上是旅行推销员的问题,而你正试图快速解决它,那么你需要得到一个近似的解决方案。根据我对TSP的经验,使用简单的贪婪搜索会产生非常好的结果,而且编码起来非常简单。有一些方法可以计算出确切的答案,但这些方法的成本非常高。如果你想要比贪婪方法提供的结果更好的结果,我很幸运地使用蚁群优化来计算近似答案。
- 为什么当你将函数的返回值乘以零时它不会短路?
- 短路运算符在enable_if
- 如何线性插值到不恒定的目的地
- 函数无目的地更改引用
- C++概念精简版:概念体中的短路
- 折叠表达式会短路吗?
- C 中的短路评估和分配
- 为什么 std::strcpy 仍然适用于像 char copyTo[0] 这样的目的地?
- c++:用于短路的 if 块语法中的多重赋值
- 中毒的无效引用和短路表达评估错误或UB
- C 用于IF-Statments和while-loops的短路
- memcpy 是否识别目的地的潜在大小?
- 短路评估与2017 C
- 问题基于从源到目的地的最短最远距离
- 如何使"短路评估"在"折叠表达式"中也可用?
- 是std :: any_of遵循短路逻辑所需的
- 当短路禁用常量表达式的计算时,是否允许在常量表达式中读取"一过一"指针
- 如何模拟短路和OpenCV
- 什么目的地<<源.rdbuf();在做什么?为什么太多的开盘关闭
- 过载操作员短路 && 和 ||在C++17