Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dijkstra Algorithm on a graph modeling a network

We have a directed graph G = (V, E) for a comm. network with each edge having a probability of not failing r(u, v) (defined as edge weight) which lies in interval [0, 1]. The probabilities are independent, so that from one vertex to another, if we multiply all probabilities, we get the the probability of the entire path not failing.

I need an efficient algorithm to find a most reliable path from one given vertex to another given vertex (i.e., a path from the first vertex to the second that is least likely to fail). I am given that log(r · s) = log r + log s will be helpful.

This is what I have so far -:

DIJKSTRA-VARIANT (G, s, t)
for v in V:
    val[v] ← ∞
A ← ∅
Q ← V to initialize Q with vertices in V.
val[s] ← 0
while Q is not ∅ and t is not in A
    do x ← EXTRACT-MIN (Q)
    A ← A ∪ {x}
    for each vertex y ∈ Adj[x]
        do if val[x] + p(x, y) < val[y]:
           val[y] = val[x] + p(x, y)

s is the source vertex and t is the destination vertex. Of course, I have not exploited the log property as I am not able to understand how to use it. The relaxation portion of the algorithm at the bottom needs to be modified, and the val array will capture the results. Without log, it would probably be storing the next highest probability. How should I modify the algorithm to use log?

like image 828
PritishC Avatar asked Oct 01 '22 14:10

PritishC


2 Answers

Right now, your code has

do if val[x] + p(x, y) < val[y]:
    val[y] = val[x] + p(x, y)

Since the edge weights in this case represent probabilities, you need to multiply them together (rather than adding):

do if val[x] * p(x, y) > val[y]:
    val[y] = val[x] * p(x, y)

I've changed the sign to >, since you want the probability to be as large as possible.

Logs are helpful because (1) log(xy) = log(x) + log(y) (as you said) and sums are easier to compute than products, and (2) log(x) is a monotonic function of x, so log(x) and x have their maximum in the same place. Therefore, you can deal with the logarithm of the probability, instead of the probability itself:

do if log_val[x] + log(p(x, y)) > log_val[y]:
    log_val[y] = log_val[x] + log(p(x, y))

Edited to add (since I don't have enough rep to leave a comment): you'll want to initialize your val array to 0, rather than Infinity, because you're calculating a maximum instead of a minimum. (Since you want the largest probability of not failing.) So, after log transforming, the initial log_val array values should be -Infinity.

like image 163
tinybike Avatar answered Oct 12 '22 21:10

tinybike


In order to calculate probabilities you should multiply (instead of add) in the relaxation phase, which means changing:

do if val[x] + p(x, y) < val[y]:
           val[y] = val[x] + p(x, y)

to:

do if val[x] * p(x, y) < val[y]:
           val[y] = val[x] * p(x, y)

Using the Log is possible if the range is (0,1] since log(0) = -infinity and log(1) = 0, it means that for every x,y in (0,1]:
probability x < probability y than:
log(x) < log(y).
Since we are maintaining the same relation (between probabilities) this modification will provide the correct answer.

I think you'll be able to take it from here.

like image 34
Nir Alfasi Avatar answered Oct 12 '22 22:10

Nir Alfasi