你的朋友正在计划前往加拿大北部一个小镇的远征
下一个冬天休息。他们研究了所有的旅行选择,并制定了指导
其节点代表中间目的地的图形和边缘代表重新加载的图形
他们。
在此过程中,他们还了解到极端天气导致这部分道路
这个世界在冬天变得非常缓慢并且可能导致大的旅行延误。他们已经
找到了一个出色的旅游网站,可以准确预测他们能够达到多快
沿着公路旅行;但是,旅行的速度取决于一年中的时间。更多
确切地说,网站回答以下形式的查询:给定边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算法,但它不正确?我会在算法中改变什么来使其适应动态变化边缘。
答案 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代码的链接。