【问题标题】:Estimating the Run Time for the "Traveling Salesman Problem"估计“旅行商问题”的运行时间
【发布时间】:2022-02-13 03:08:36
【问题描述】:
【问题讨论】:
标签:
optimization
time
graph
combinations
traveling-salesman
【解决方案1】:
我听说如果现代计算机使用“蛮力”(即精确解)解决这个问题 - 如果城市超过 15 个,计算机所花费的时间将超过一百年!
这并不完全正确。而朴素的蛮力算法以n! 的复杂度运行。使用动态编程的much better algorithm 在O(n^2 2^n) 中运行。只是给你一个想法,n=25,n! ≃ 2.4e18 而n^2 2^n ≃ 1e12。前者太大而无法实用,而第二个可能没问题,尽管在 PC 上需要很长时间(应该记住,两种算法复杂性都包含一个隐藏的常量变量,该变量在计算实际执行时间方面起着重要作用)。我使用基于 Held-Karp 算法的优化动态规划解决方案,在我的机器上以相对合理的时间(即不超过几分钟的计算)计算了 20 个城市的 TSP。
请注意,在实践中,启发式通常用于大幅加快计算速度,但代价是次优解决方案。与以前的精确算法(具有相对较小指数的多项式算法)相比,某些算法可以在很短的时间内提供良好的结果,并且对结果的质量有固定的限制(例如,找到的距离不能大于 2 倍最优解)。最后,启发式通常可以在合理的时间内找到非常好的结果。一种简单的启发式方法是在使用欧几里德距离的情况下避免交叉线段(AFAIK 具有交叉线段的解决方案总是次优的)。
我的问题:我们是否可以使用一些公式来估算计算机使用“蛮力”解决旅行商问题所需的时间?
由于朴素算法受计算限制且非常简单,因此您可以根据运行时间复杂度进行这种近似。但要获得相对精确的执行时间近似值,您需要校准,因为并非所有处理器和实现的行为方式都相同。您可以假设运行时间为C n!,并通过测量实际蛮力实现所花费的计算时间来通过实验找到C 的值。另一种方法是根据目标处理器的低级架构属性(例如频率、使用的核心数量等)从理论上找到C 的值。假设基准测试正确完成并且点数足够大,前者会更加精确。此外,第二种方法需要非常了解现代处理器的工作方式。
在数值上,假设运行时间t ≃ C n!,我们可以说ln t ≃ ln(C n!) ≃ ln(C) + ln(n!)。基于Stirling's approximation,我们可以说ln t ≃ ln C + n ln n + O(ln n),所以ln C ≃ ln t - n ln n - O(ln n)。因此,ln C ≃ ln t - n ln n - O(ln n),最后是C ≃ exp(ln t - n ln n)(近似于O(n))。话虽如此,斯特林的近似值可能不够精确。使用二分搜索以数值方式计算逆 gamma function(它是阶乘的推广)应该为 C 提供更好的近似值。
每一个 N!路径将需要“N”次计算
好吧,稍微优化的蛮力算法不需要执行N 计算,因为可以预先计算部分路径长度。最后的循环只需要从应该存储在 L1 缓存中的小数组中读取预先计算的和(因此读取/存储只需要不超过几个延迟周期)。