Oto rozwiązanie oparte na ideach zawartych w odpowiedzi Realza Slawa. Jest to w zasadzie ponowna prezentacja jego pomysłów, które mogą być jaśniejsze lub łatwiejsze do naśladowania. Plan jest taki, że będziemy postępować w dwóch krokach:
Najpierw zbudujemy wykres o następującej właściwości: każda ścieżka od s do t w S jest najkrótszą ścieżką od s do t w G , a każda najkrótsza ścieżka od s doSstSstGs w G jest obecna w S . Zatem S zawiera dokładnie najkrótsze ścieżki w G : wszystkie najkrótsze ścieżki i nic więcej. Tak się składa, że S będzie DAG.tGSSGS
Następnie zostanie równomiernie próbki losowo wszystkich ścieżek z na T w S .stS
To podejście uogólnia się na arbitralnie skierowany wykres , o ile wszystkie krawędzie mają dodatnią wagę, więc wyjaśnię mój algorytm w tych terminach. Niech w ( u , v ) oznacza ciężar na krawędzi u → v . (Uogólnia to podane przez ciebie stwierdzenie problemu. Jeśli masz nieważony wykres, po prostu załóż, że każda krawędź ma wagę 1. Jeśli masz niekierowany wykres, traktuj każdą nieukierowaną krawędź ( u , v ) jak dwie skierowane krawędzie u → v i v → u .)Gw(u,v)u→v(u,v)u→vv→u
Etap 1: Ekstrakt z . S Uruchom algorytm najkrótszych ścieżek z jednego źródła (np. Algorytm Dijkstry) na , zaczynając od źródła s . Dla każdego wierzchołka v w G , niech d ( s , v ) oznacza odległość od s do vGsvGd(s,v)sv .
Teraz zdefiniuj wykres w następujący sposób. Składa się z każdej krawędzi u → v tak, że (1) u → v jest krawędzią w G , i (2) d ( s , v ) = d ( s , u ) + w ( u , v ) .Su→vu→vGd(s,v)=d(s,u)+w(u,v)
Wykres ma kilka dogodnych właściwości:S
Każda najkrótsza ścieżka od do t w G istnieje jako ścieżka w S : najkrótsza ścieżka s = v 0 , v 1 , v 2 , … , v k = t w G ma właściwość, że d ( s , v i + 1 ) = d ( s , v i ) + w ( v i , v istGSs=v0,v1,v2,…,vk=tG, dzięki czemu krawędź V i → V i + 1 jest obecny wS.d(s,vi+1)=d(s,vi)+w(vi,vi+1)vi→vi+1S
Każda ścieżka w z S na T jest najkrótsza ścieżka w G . W szczególności rozważ dowolną ścieżkę w S od s do t , powiedzmy s = v 0 , v 1 , v 2 , … , v k = t . Jego długość jest sumą wag jego krawędzi, a mianowicie ∑ k i = 1 w ( v i - 1 , v i )SstGSsts=v0,v1,v2,…,vk=t∑ki=1w(vi−1,vi), Ale z definicji , to suma Σ k i = 1 ( d ( S , V, I ) - d ( a , v I - 1 ) , które teleskopy D ( s , t ) - d ( s , s ) = d ( s , t ) . Dlatego ścieżka ta jest najkrótszą ścieżką od s do t w GS∑ki=1(d(s,vi)−d(s,vi−1)d(s,t)−d(s,s)=d(s,t)stG.
Finally, the absence of zero-weight edges in G implies that S is a dag.
Step 2: sample a random path. Now we can throw away the weights on the edges in S, and sample a random path from s to t in S.
To help with this, we will do a precomputation to compute n(v) for each vertex v in S, where n(v) counts the number of distinct paths from v to t. This precomputation can be done in linear time by scanning the vertices of S in topologically sorted order, using the following recurrence relation:
n(v)=∑w∈succ(v)n(w)
succ(v)vsucc(v)={w:v→w is an edge in S}n(t)=1.
Next, we use the n(⋅) annotation to sample a random path. We first visit node s. Then, we randomly choose one of the successors of s, with successor w weighted by n(w). In other words:
choosesuccessor(v):
n = 0
for each w in succ(w):
n = n + n(w)
r = a random integer between 0 and n-1
n = 0
for each w in succ(w):
n = n + n(w)
if r < n:
return w
To choose a random path, we repeatedly iterate this process: i.e., v0=s, and vi+1= choosesuccessor
(vi). The resulting path is the desired path, and it will be sampled uniformly at random from all shortest paths from s to t.
Hopefully this helps you understand Realz Slaw's solution more easily. All credit to Realz Slaw for the beautiful and clean solution to this problem!
The one case this doesn't handle is the case where some edges have weight 0 or negative weight. However, the problem is potentially not well-defined in that case, as you can have infinitely many shortest paths.