Algorithm 带燃料约束和可变加油量的最短路径算法

Algorithm 带燃料约束和可变加油量的最短路径算法,algorithm,graph,shortest-path,Algorithm,Graph,Shortest Path,假设你有一个无向加权图。您希望找到从源节点到目标节点的最短路径,同时从一些初始“燃料”开始。每条边的重量等于穿过边时损失的“燃料”量。在每个节点上,您可以将预定量的燃油添加到燃油计数中-该值可以为0。一个节点可以被访问多次,但燃料只能在您第一次到达该节点时添加**所有节点都可以提供不同数量的燃料 这个问题可能与从a镇开往B镇的火车有关。尽管这两个镇通过一条简单的轨道直接相连,但煤炭短缺,因此火车没有足够的燃料来完成这一行程。取而代之的是,从A镇到C镇的路程要短得多,而C镇有足够的燃料,可以往返A

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

这个问题可能与从a镇开往B镇的火车有关。尽管这两个镇通过一条简单的轨道直接相连,但煤炭短缺,因此火车没有足够的燃料来完成这一行程。取而代之的是,从A镇到C镇的路程要短得多,而C镇有足够的燃料,可以往返A镇,然后再前往B镇。因此,最短的路径是A到C镇的距离加上C到A镇的距离加上A到B镇的距离。我们假设燃料成本和距离是相等的


我见过这样一个例子,节点总是将“油箱”充满到其最大容量,但我没有看到一个算法可以处理不同节点的不同加油量。解决这个问题的有效算法是什么?

这个问题没有有效的算法。如果您获取一个大小为
n
的现有图形
G
,则可以为每个边赋予权重1,为每个节点赋予5的存款,然后添加一个新的节点,该节点将尝试移动到连接到每个节点的权重为
4*(n-1)
。现在,图中从源节点到目标节点的路径的存在性等价于
G
中哈密顿路径的存在性,这是一个已知的np完全问题。(有关详细信息,请参阅。)


也就是说,对于大多数图,您可以做得比简单的递归解决方案更好。首先从目标节点执行广度优先搜索,以便每个节点到目标的距离都是已知的。现在你可以借用Dijkstra的A*搜索的主要思想。搜索来自源的所有路径,使用优先级队列始终尝试增长到目标的当前距离+最小距离最小的路径。为了减少工作量,您可能还希望放弃所有返回到他们以前访问过的节点的路径,但燃料较低的路径除外。(这将避免在燃料耗尽时绕着回路来回移动的愚蠢路径。)

不幸的是,这个问题是NP难问题。给定一个从s到t的旅行商路径实例,其决策阈值为d(是否有一条st路径访问长度最多为d的所有顶点?),按如下所示对该问题进行一个实例。添加一个新的目标顶点,该顶点通过一条很长的边连接到t。给起动燃料d。设置新边的长度和除目标之外的每个顶点处的燃料,以便(1)所有顶点处的总燃料等于新边的长度(2)在不收集所有燃料的情况下无法使用新边。当且仅当有一条短的旅行路线时,才有可能到达目的地

因此,这个问题的算法将类似于TSP的算法。通过在源、目标和具有非零燃料的顶点上构造完整的图进行预处理。每条边的长度等于距离

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

否则,游戏可能是整数规划。这里有一个公式,很可能是可以改进的。如果将定向边
e
作为
i
第i步(从第0步开始计数),则设
x(i,e)
为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}
最小化求和i求和{边e}代价(e)x(i,e)
从属于
对于每个i,对于每个顶点v,
头为v}x的和{边e(i,e)-尾为v}x的和{边e(i+1,e)=
-如果i=0且v为源,则为1
如果i+1=T且v为目标,则为1
否则为0

对于每个顶点v,sum_i sum_{边e,头部v}x(i,e)假设燃油消耗为正重量,并将燃油添加为负重量,另外将初始可用燃油视为另一条负加权边,您可以将其作为单源最短路径求解

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