Algorithm 具有两个条件的最短路径问题

Algorithm 具有两个条件的最短路径问题,algorithm,graph,Algorithm,Graph,假设我有一个有向图G(V,E,w,c),其中w是每条边的正权重,c是每条边的成本为1或0。我需要找到一个算法,对于给定的源垂直u,找到从u到V中有成本的每条垂直的最短路径≤ k(其中k≥1) 我试图修改贝尔曼·福特的算法,但似乎找不到解决办法。让我重申一下我对这个问题的理解 对于成本不超过k的所有顶点,您需要从顶点u到达的最小权重路径 你需要综合各种想法才能达到目的 假设路由节点对象具有以下属性:成本,权重,节点,最后路由节点和自动递增的id。这是一个链接列表,将我们带回原始节点,让我们重建路

假设我有一个有向图G(V,E,w,c),其中w是每条边的正权重,c是每条边的成本为1或0。我需要找到一个算法,对于给定的源垂直u,找到从u到V中有成本的每条垂直的最短路径≤ k(其中k≥1)


我试图修改贝尔曼·福特的算法,但似乎找不到解决办法。

让我重申一下我对这个问题的理解

对于成本不超过
k
的所有顶点,您需要从顶点
u
到达的最小权重路径

你需要综合各种想法才能达到目的

假设
路由节点
对象具有以下属性:
成本
权重
节点
最后路由节点
和自动递增的
id
。这是一个链接列表,将我们带回原始节点,让我们重建路由。我们通过
成本
,然后
重量
,然后
id
对它们进行比较

我们有一个哈希/字典/任何你想叫它的东西,它将节点映射到到达该节点的最低权重
RouteToNode
对象。称之为
bestRoute

我们有一个
todo
列表,其中包含我们尚未处理的
RouteToNode
s,这是一个始终返回最小
RouteToNode
的优先级队列。注意,它总是从最低成本返回到最高成本

我们从没有任何内容的
bestRoute
开始,一个
todo
队列只有一个
RouteToNode
,即:

{
    id: 0,
    cost: 0,
    weight: 0,
    node: u,
    lastRouteToNode: null
}
现在我们执行以下伪代码:

while todo is not empty:
    thisRouteToNode = todo.pop()
    if thisRouteToNode.node not in bestRoute or
      thisRouteToNode.weight < bestRoute[thisRouteToNode.node].weight:
        bestRoute[thisRouteToNode.node] = thisRouteToNode
        for edge adjacent to thisRouteToNode.node:
            construct nextRouteToNode by adding edge
            if nextRouteToNode.cost <= k:
                todo.push(nextRouteToNode)
当todo不为空时:
thisRouteToNode=todo.pop()
如果thisRouteToNode.node不在最佳路由中,或
thisRouteToNode.weight<最佳路由[thisRouteToNode.node]。重量:
bestRoute[thisRouteToNode.node]=thisRouteToNode
对于与thisRouteToNode.node相邻的边:
通过添加边构造nextRouteToNode

如果是nextRouteToNode.cost,我认为你不能轻易让贝尔曼福特解决这个问题。我认为修改Dijkstra会更容易,特别是因为你只对一个源的距离感兴趣。@SergGr我认为这不能用贪婪的方法解决,因为只有找到一个顶点的最小路径,我们才能知道它是否在k.Epitheoritis的边界内,如果你仔细观察@btilly-answer,你可能会注意到这正是修改过的Dijkstra,我看不出它不起作用的原因(如果实施得当,我认为答案不是很清楚)。你有什么反例吗?主要的想法是,在做Dijkstra时,你可以安全地提前切断那些打破
总成本>=k
限制的分支。您仍然可能需要检查更多的候选路径,因为较低的权重并不能保证更好,因为我们可能没有足够的成本来完成任务。但实现起来并不难。@SergGr这就是我的意思:考虑让边A->B的成本为10,权重为20,另一个A->B的成本为12,权重为5,B->C的成本为7,权重为1,另一个B->C的成本为5,权重为50。我们不应该保证A->B(12,5)在最短路径树中,尽管只访问B是最好的。但这只有在访问C之后才能理解。这里的时间完整性是多少?@Epitheoritis32最坏的情况是
O(kelog(kee))
。这表示您以不断降低的成本反复访问节点,并将其所有边缘都放入待办事项列表中的情况。也就是说,在实践中,我希望您更接近
O(E log(E))