动态最短路径

时间:2017-11-20 11:37:53

标签: algorithm graph shortest-path

你的朋友正在计划前往加拿大北部一个小镇的远征 下一个冬天休息。他们研究了所有的旅行选择,并制定了指导 其节点代表中间目的地的图形和边缘代表重新加载的图形 他们。 在此过程中,他们还了解到极端天气导致这部分道路 这个世界在冬天变得非常缓慢并且可能导致大的旅行延误。他们已经 找到了一个出色的旅游网站,可以准确预测他们能够达到多快 沿着公路旅行;但是,旅行的速度取决于一年中的时间。更多 确切地说,网站回答以下形式的查询:给定边e =(u,v) 连接两个站点u和v,并从位置u给出建议的起始时间t, 站点将返回值fe(t),预计到达时间为v。网站保证 1 fe(t)> t为每个边缘e和每个时间t(你不能及时向后移动),那个 fe(t)是t的单调递增函数(也就是说,你不能通过启动来提前到达 后来)。除此之外,函数fe可以是任意的。例如,在哪些地区 旅行时间不随季节变化,我们会有fe(t)= t + e, where e是 从边缘开始到结束所需的时间e。 您的朋友希望使用该网站来确定最快的旅行方式 从起点到预定目的地的有向图。 (你应该假设 他们从时间0开始,并且网站做出的所有预测都是完全的 正确。)给出一个多项式时间算法来执行此操作,我们将单个查询视为 网站(基于特定边缘e和时间t)作为单个计算步骤。

    def updatepath(node):
        randomvalue = random.randint(0,3)
        print(node,"to other node:",randomvalue)
        for i in range(0,n):
            distance[node][i] = distance[node][i] + randomvalue

    def minDistance(dist,flag_array,n):
        min_value = math.inf
        for i in range(0,n):
            if dist[i] < min_value and flag_array[i] == False:
                min_value = dist[i]
                min_index = i
        return min_index

    def shortest_path(graph, src,n):
        dist = [math.inf] * n
        flag_array = [False] * n
        dist[src] = 0

        for cout in range(n):
            #find the node index that have min cost
            u = minDistance(dist,flag_array,n)
            flag_array[u] = True
            updatepath(u)
            for i in range(n):
                if graph[u][i] > 0 and flag_array[i]==False and dist[i] > dist[u] + graph[u][i]:
                    dist[i] = dist[u] + graph[u][i]
                    path[i] = u
        return dist

我应用了Dijkstra算法,但它不正确?我会在算法中改变什么来使其适应动态变化边缘。

1 个答案:

答案 0 :(得分:1)

那么,关键点是功能是单调增加的。有一种算法可以利用这个属性,它被称为 A *

累积成本:您的教授希望您使用两个距离,一个是累积成本(这很简单,从之前的成本增加到移动到下一个节点所需的成本/时间)。

启发式费用:这是一些预测成本。

Disjkstra方法不起作用,因为您正在使用启发式成本/预测累积成本

单调递增意味着 h(A)&lt; = h(A)+ f(A..B)。只是说如果你从节点移动 A 节点 B 然后成本不应小于前一节点(在本例中为A),这是启发式+累积。如果此属性成立,则第一条路径 A * 选择始终是目标的路径,它永远不需要回溯。

注意:此算法的强大功能完全取决于您预测价值的方式。

如果您低估了将使用累计值更正的值,但如果您高估了该值,则会选择错误的路径。

算法:

Create  a Min Priority queue.
insert initial city in q.

while(!pq.isEmpty() && !Goalfound) Node min = pq.delMin() //this should return you a cities to which your distance(heuristic+accumulated is minial). put all succesors of min in pq // all cities which you can reach, you can better make a list of visited cities s that queue will be efficient by not placing same element twice. Keep doing this and at the end you will either reach goal or your queue will be empty

<强>附加

在这里,我使用A *实现了8-puzzle-solve,它可以让您了解如何定义成本并确保其有效。

`

private void solve(MinPQ<Node> pq, HashSet<Node> closedList) {
        while(!(pq.min().getBoad().isGoal(pq.min().getBoad()))){
            Node e = pq.delMin();
            closedList.add(e);
            for(Board boards: e.getBoad().neighbors()){
                Node nextNode = new Node(boards,e,e.getMoves()+1);
                if(!equalToPreviousNode(nextNode,e.getPreviousNode()))
                      pq.insert(nextNode);
               }
            }
        Node collection = pq.delMin();
            while(!(collection.getPreviousNode() == null)){
                this.getB().add(collection.getBoad());
                collection =collection.getPreviousNode();
        }
            this.getB().add(collection.getBoad());
            System.out.println(pq.size());
    }

此处有full代码的链接。