具有燃料约束和可变加油的最短路径算法

时间:2014-09-16 01:11:51

标签: algorithm graph shortest-path

假设您有一个无向加权图。您希望找到从源到目标节点的最短路径,同时从一些初始“燃料”开始。每条边的重量等于你在边缘丢失的“燃料”量。在每个节点,您可以为燃料计数添加预定量的燃料 - 该值可以为0.可以多次访问节点,但只有在您第一次到达节点时才会添加燃料。 **所有节点都可以提供不同数量的燃料。

这个问题可能与从A镇到B镇的火车有关。虽然两者都是通过简单的轨道直接连接,但煤炭短缺,所以火车没有足够的燃料来进行旅行。相反,它必须进行从A镇到C镇的更短的旅程,已知有足够的燃料来覆盖返回A然后继续前往B.因此,最短的路径是从A到C的距离加上从C到A的距离加上从A到B的距离。我们假设燃料成本和距离相等。

我已经看到一个示例,其中节点总是填充“坦克”达到其最大容量,但我还没有看到一种算法在不同节点处理不同的加油量。什么是解决此问题的有效算法?

3 个答案:

答案 0 :(得分:2)

此问题没有有效的算法。如果您使用大小为G的现有图表n,则可以为每个边缘提供1的权重,每个节点的存款为5,然后添加您尝试前往连接的新节点每个节点的权重为4 * (n -1)。现在,在该图中存在从源到目标节点的路径等同于G中存在哈密顿路径,这是已知的np完全问题。 (有关详细信息,请参阅http://en.wikipedia.org/wiki/Hamiltonian_path。)

那就是说,对于大多数图表来说,你可以比天真的递归解决方案做得更好。首先从目标节点进行广度优先搜索,以便知道每个节点到目标的距离。现在你可以借用Dijkstra的A *搜索的主要思想。从源搜索所有路径,使用优先级队列始终尝试生成当前距离+目标最小值的路径。为了减少工作量,您可能还想丢弃已经返回到之前访问过的节点的所有路径,除了燃料较低。 (这将避免在燃料耗尽时来回循环的愚蠢路径。)

答案 1 :(得分:2)

不幸的是,这个问题是NP难的。给定一个从s到t的旅行推销员路径的实例,其具有决策阈值d(是否存在访问所有顶点长度最多为d?的st路径),如下所述制作该问题的实例。添加一个连接到t的新目标顶点很长的边缘。给出启动燃料d。设置新边缘的长度和除目的地之外的每个顶点的燃料,以便(1)所有顶点的总燃料等于新边缘的长度(2)如果没有,则不可能使用新边缘收集所有的燃料。当且仅当有短途旅行推销员路径时,才有可能到达目的地。

因此,该问题的算法将类似于TSP的算法。通过使用非零燃料在源,目标和顶点上构建完整图来预处理。每条边的长度等于距离。

如果有足够少的特殊顶点,那么指数时间(O(2 ^ n poly(n)))动态编程是可能的。对于由顶点子集(按照非减小的大小顺序)和该子集中的顶点组成的每对,确定访问所有子集并在指定顶点结束的最便宜方式。通过使用子集的预先计算结果减去顶点和每个可能的最后一个航路点来有效地执行此操作。有一种优化可以修剪比已知解决方案更糟糕的子解决方案,如果没有必要使用很多航点,这可能会有所帮助。

否则,播放可能是整数编程。这是一个很有可能改进的配方。如果有针对边x(i, e)被视为e步(从第0个计算),则i为1的变量,其他为0.允许f(v)为可用燃料在顶点v。让y(i)成为i步之后的燃料变量。假设步骤总数为T

minimize sum_i sum_{edges e} cost(e) x(i, e)
subject to
for each i, for each vertex v,
    sum_{edges e with head v} x(i, e) - sum_{edges e with tail v} x(i + 1, e) =
        -1 if i = 0 and v is the source
         1 if i + 1 = T and v is the target
         0 otherwise
for each vertex v, sum_i sum_{edges e with head v} x(i, e) <= 1
for each vertex v, sum_i sum_{edges e with tail v} x(i, e) <= 1
y(0) <= initial fuel
for each i,
    y(i) >= sum_{edges e} cost(e) x(i, e)
for each i, for each vertex v,
    y(i + 1) <= y(i) + sum_{edges e} (-cost(e) + f(head of e)) x(i, e)
for each i, y(i) >= 0 
for each edge e, x(e) in {0, 1}

答案 2 :(得分:0)

假设燃油消耗为正重量并且选择将燃油添加为负重量并另外将初始燃油作为另一个负加权边缘处理,则可以使用Bellman Ford将其解决为单一来源最短路径。

根据this answer,在其他地方,可以通过在两个方向上用两个替换每个边来解决无向图。我不确定的唯一限制是你只能加油一次的部分。这可以通过算法自然地解决,但我不确定。