40 likes | 165 Views
The scenario: have an army of ants (or whatever) all starting at the START vertex (say, A), moving at unit speed away from it in all directions. Whenever a group of ants hits a vertex, they split apart going in all directions. Clearly, the first ant to hit a node has gone along the
E N D
The scenario: have an army of ants (or whatever) all starting at the START vertex (say, A), moving at unit speed away from it in all directions. Whenever a group of ants hits a vertex, they split apart going in all directions. Clearly, the first ant to hit a node has gone along the shortest path. Some things to notice about these ants: 1. If an ant gets to a vertex that's already been visited, it can quit since it can't possibly be the first to anywhere. (this will map to the "if V is visited..." line below) 2. In fact, there's no reason to even start down a path to a vertex if you know it's been visited before. (this will map to the "if X is visited..." line below) Say we wanted to implement this idea in a computer program. What would we need to keep track of? In terms of the vertices, we could keep track of: unseen[X] = false if X has already been visited by the ants val[X] = the time the ants first got there (the length of the shortest path to X) dad[X] = where those ants came from. Then we also need to keep track of the ants: for each group of ants currently active we want to know where they are (what edge are they on) and when are they going to get to the endpoint they're heading towards. Then, in each step of the algorithm, we just need to find out what the next event is ("event" == ants hitting a vertex) and update our data structures.
Priority-First SearchMinimal Spanning Tree init: update (start, start, 0) into Pqueue set all val[k] = 0 and unseen[k] = true While queue not empty: (U, V, priority) = pqueue.removeMin(); if V already visited, continue; // corresponds to (1) above mark V as visited (seen). set dad[V] = U. set val[V] = priority for each unvisted (unseen) neighbor X of V: update (V, X, weight(VXedge)) into pqueue.
Priority-First SearchShortest Path init: update (start, start, 0) into Pqueueset all val[k] = 0 and unseen[k] = true While queue not empty: (U, V, priority) = pqueue.removeMin(); if V already visited, continue; // corresponds to (1) above mark V as visited (seen). set dad[V] = U. set val[V] = priority for each unvisted (unseen) neighbor X of V: update (V, X, val[V] + weight(VX edge)) into pqueue.
How long does the above algorithm take? Answer: there are at most |E| "inserts" (because once you send ants down an edge, you will never send them down that edge again) and so also at most |E| removeMins. So, the time is O(|E|*(time for insert) + |E|*(time for removeMin)) Max number of items in pqueue at any point in time is |E|. So, if we can get the inserts and removeMins to O(log n) time we will have time = O(|E| * log(|E|)) We can do this by using a min-heap. To removemin we take the root off (that's the minimum) and then re-make the heap by replacing it with the rightmost leaf and doing a "downheap"/"siftUp" procedure.