修改贝尔曼-福特算法以维护基于成本的有序列表

Modifying the Bellman-Ford Algorithm to maintain an ordered list based on cost

本文关键字:于成本 列表 维护 贝尔 算法 修改      更新时间:2023-10-16

假设您正在寻找火车之旅。您会对乘车的价格以及乘车所需的时间感兴趣。现在假设您有一个图表,其中每条边都有成本和持续时间,并且您希望在图形中找到不超过给定最大成本的最短持续时间路径(任意两个顶点之间可能有多个边)。

这是我遇到的问题。我认为解决这个问题的最好方法是修改贝尔曼-福特算法。

这是我到目前为止所拥有的:

// A struct to represent an Edge in graph
struct Edge
{
int source, dest, cost, duration;
};
// A struct to reporesented a connected, directed 
//and wieghted graph
struct Graph
{
int V, E;
struct Edge* edge;
};
// Creates Graph with V vertices and E edges
struct Graph* createGraph(int V, int E)
{
struct Graph* graph = new (struct Graph);
graph -> V = V;
graph -> E = E;
graph -> edge = new Edge[E];
return graph;
} 

我已经用他们需要的所有信息填充了结构。现在我只需要根据成本"组织"数据。所以我意识到对于每个顶点,我需要存储一个通向它的路径列表。对于我认为需要将路径从第一个顶点列表复制到第二个顶点列表(增加成本和距离)。但是我如何实际编写这个,我被困在上面的部分。

这个问题是一个经过充分研究的问题:公共交通网络中的行程规划问题。
基于Bellman-Ford的方法可能会变得有问题并且过于昂贵,具体取决于网络,因为您无法考虑顶点已被"访问",或者在算法执行期间已经计算出到达顶点的最短路径。
这些概念("访问"或"最短")仅适用于单个客观最短路径问题。这是因为给定u, v几个顶点,有趣的路径数量可能呈指数级增长,因为您不能只考虑更快或更便宜的选择。您必须将任何路径保留在内存中,以便没有其他路径更便宜,更快,并且如果您开始在现实网络上工作,则此数量的路径可能会迅速失控(这可能非常大,~100k停止和数百万次旅行)。

我建议你阅读多目标最短路径问题,还有一个事实,即通常,代表网络的图是一个随时间变化的图。
我认为值得您阅读有关多目标最短路径的页面,以了解该领域使用的主要技术(帕累托集合或帕累托边界的概念对于掌握这个问题非常重要),甚至本文的第 2 节和第 4 节,它描述了有关此类技术的实际技术水平。

尽管看起来很复杂,但它们中的大多数都可以运行得非常快(比Dijkstra快数十万倍,仍然比任何基于A *的方法快得多),并且对于其中一些来说,实现起来并不太难(例如,CSA不太复杂,并且运行得非常快,它可以在国家规模的网络上在几毫秒内计算一个简单的查询)。

按成本组织数据的典型方法是使用std::priority_queue来存储路径。 当您发现路径时,您将路径放入队列中,然后它们首先从队列中最便宜的中出来。

你必须为放入priority_queue中的任何对象实现比较运算符,但这并不难做到。