Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
We are given a directed graph G = (V, E) on which each edge (u, v) ∈ E has an associated
value r(u, v), which is a real number in the range 0 ≤ r(u, v) ≤ 1 that represents the reliability of a communication channel from vertex u to vertex v. We interpret r(u, v) as the
probability that the channel from u to will not fail, and we assume that these probabilities
are independent. Give an efficient algorithm to find the most reliable path between two given
vertices.
a
/ \
b<--c a directed to c; c directed to b; b directed to a
Let's say this is graph G = (V, E); vertex a is the root, one of the edge is a to c. a = u & c = v so edge is (u, v). I want to use Dijkstra’s algorithm to solve this, but not sure how.
a
\
b<--c path c: a -> c & b: a -> c -> b
Can someone explain the most reliable path in the simplest way possible?
This question is from Introduction to Algorithms, 3rd edition, chp 24.3
Thanks in advance!
We interpret r(u, v) as the probability that the channel from u to
will not fail, and we assume that these probabilities are independent.
From this you can deduce that the probability that a given path will not fail is equal to the product of the r(u,v) of all edges (u,v) that make up the path.
You want to maximize that product.
This is exactly like the shortest path problem, for which you surely know an algorithm, except instead of minimizing a sum, you are trying to maximize a product.
There is a cool tool to go from products to sums: it's the logarithm. Logarithm is an increasing function, thus maximizing a product is the same as maximizing the logarithm of that product. But logarithm has the additional cool property that the logarithm of a product is equal to the sum of the logarithms:
log(a * b * c * d * ...) = log(a) + log(b) + log(c) + log(d) + ...
Thus maximizing the product of the reliabilities r(u,v) is the same as maximizing the sum of the log-reliabilities log(r(u,v)).
Since the reliabilities are probabilities of the edges, they are values between 0 (excluded) and 1 (included). You can exclude 0 because if an edge had a reliability of 0, you can remove that edge from the graph. Since 0 < r(u,v) <= 1, it follows that log(r(u,v)) is negative or 0.
So you are trying to maximize a sum of negative values. This is exactly the same as minimizing the sum of the opposite values.
Thus: apply your shortest-path algorithm, using -log(r(u,v)) as the lengths of the edges.
Related
Having a directed graph G with edges having positive weights, we define the cost of a path the difference between the edge with minimum weight and maximum weight. The goal is to find a path with maximum cost among other paths. We don't need to return the path itself just the maximum cost.
If x is the number of vertices and y is the number of edges then x < 10^5 and y < min(x^2,10^5). The time limit is 1 second.
Based on the bounds I think this problem has to be solved in O(x+y) time.
So based on the problems properties ans some studying of other algorithms I thought that on possible answer may contain multiple DFS's (like the SCC problem). I also find a similar problem with Dijkstra's algorithm that can be modified for this problem but I'm not very sure that the complexity would be OK. Also there are some other questions similar to mine however the answers were of O(m^2) or higher which were not very efficient.
Other than what was mentioned above I have no idea to solve the problem and some insight would be very helpful. Thanks
Solution:
Due to the fact that our graph can have cycles, this complicates things for us. Let's build a new graph in which we "compress" all the components of a strong connection into a single vertex, so new graph will be acyclic. During this process let's memorize maximum(maximumWeight[v]) and minimum(minimumWeigh[v]) weights of the edges for each strongly connected components.
We spent O(|V| + |E|) time for it, where |V| is count of vertexes and |E| is count if edges.
After that let's make a topological sorting of given graph in O(|V|+|E|) time complexity. Then let's calculate simple DP.
dpMax[v] - the maximum weight of the edge to which there is a path from this vertex.
dpMin[v] - the minimum weight of the edge to which there is a path from this vertex.
Default value:
If vertex v is strongly connected component, then maximum and minimum weights already calculates in maximumWeight[v] and minimumWeigh[v], so dpMax[v] = maximumWeight[v] and dpMin[v] = minimumWeight[v].
Otherwise maximumWeight[v] = -Infinity and minimumWeigh[v] = Infinity.
In topological order let's improve our DP for each vertex:
int answer = -Infinity;
for(auto v : vertexesInTopologicalOrder) {
int newMinDp = dpMin[v], newMaxDp = dpMax[v];
for(auto e : v.outgoingEdges) {
int l = dpMin[v];
int r = dpMax[v];
l = min(l, e.weight);
r = max(r, e.weight);
l = min(l, dpMin[e.target]);
r = max(r, dpMax[e.target]);
answer = max(answer, e.weight - l);
answer = max(answer, r - e.weight);
newMinDp = min(newMinDp, l);
newMaxDp = max(newMaxDp, r);
}
dpMin[v] = newMinDp;
dpMax[v] = newMaxDp;
}
Since we calculating DP in topological order, the DP at achievable vertexes have already been calculated.
For a better understanding, let's look at an example.
Let's say we have such an initial graph.
After compression, the graph will look something like this.
After topological sorting, we get this order of vertices. (Green numbers)
Sequentially calculate all DP values, along with updating the answer.
Final answer 6 will be achieved during calculating top vertex DP.
I hope it turned out to be quite detailed and clear. Final time complexity is O(|V|+|E|).
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have an app where people can give marks to each other, out of ten points. At midnight, each day, I would like to compute a "match" for each member. I would like to make everyone as much happy as possible, in average.
So at the midnight, I have an oriented graph like so :
1 -> 2 : 7.5 // P1 give a 7.5/10 to P2
1 -> 3 : 5
1 -> 4 : 9
2 -> 3 : 6
2 -> 1 : 4
etc.
To make things more simple let's say that if P1 give P2 a 5 and P2 give P1 a 7, the match P1 - P2 will have a weight of 5 + 7 - (7-5)/2 = 11 (I substract the difference because, for a same sum of grades, it's better if they are close to each other, that is, a (7/10 - 7/10) is a better match than a (10/10 - 4/10)).
So with this done, we have a non-oriented graph. Mathematically speaking, for my purpose, I think that I need to find an algorithm that finds, among all the maximum-sized matchings that have this graph, the one that has the maximum weight sum. Does such an algorithm exist ?
I've already looked into "Mariage stable problem" and "assignment problem" but these are for graph that can be divided in 2 classes (men/women, men/task ..)
A way to do that is to modify your graph and then find a maximum weight matching on it.
I need to find an algorithm that finds, among all the maximum-sized matchings that have this graph, the one that has the maximum weight sum. Does such an algorithm exist ?
Let's consider your graph G = (V, E, w) where w is your weight function. Let's denote by n the size of V, i.e the number of vertices in your graph, and by M the maximum weight among the edges.
Then, all you have to do is to define w' in this way: for any edge e of E, w'(e) = w(e) + n*M.
In this case, a maximum weight matching on G' = (V, E, w') corresponds to a matching of maximum size in G = (V, E, w) that also has a maximum weight.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am just learning Dijkstra algorithm and just a little bit confuse in this
If min(A,B) = x;
min(A,C) = y;
min(B,C) = must be x-y;
Please justify it or i am wrong?
Okay here's what you meant to say:
I will be referring to a directed non-negative weight graph in all of this.
The shortest path problem:
For a digraph G and a node r in V and a real cost vector (c_e:e in E) (I wish we had LaTeX here)
we wish to find:
for each v in V a dipath from r to v of least cost (supposing it exists)
Here's the gist of what you want:
suppose we know there's a path from r to v of cost y_v for each v in V, and we find an edge vw in E satisfying y_v + c_vw < y_w
Since appending vw to the dipath to v (to get a path to w) gives a path of length y_v+c_vw
A least cost dipath satisfies:
y_v+c_vw >= y_w for all vw in E
We call such a y vector a "feasible potential"
Proposition: y_v is minimal
Let y be a feasible potential, and let P be a dipath from r to v, then it follows c(P) >= y_v
Proof:
c(P) = sum c_ei (the the ith edge in the path's cost)
Recall that a feasible potential statisfies y_v + c_vw >= y_w
So c_vw >= y_w - y_v this is what you have
Thus
c(P) >= sum (y_vi-y_v{i-1}) (the cost to the ith item take the cost of the previous one)
if you write it as sum (-y_v{i-1} + y_vi) then expand the sum: (y_v0 = 0 obviously)
-y_v0+y_v1 -y_v1 + y_v2 - .... -y_v{k-2} + y_v{k-1} -y_v{k-1} + y_vk
you see all the terms cancel out, giving:
c(P) >= y_vk - y_v0 = y_vk
Thus we have shown c(P) >= y_vk
It is wrong, think about any equilateral triangle, the difference of two sides is 0 and the length of the third size is not.
I'm trying to come up with a reasonable algorithm for this problem:
Let's say we have bunch of locations. We know the distances between each pair of locations. Each location also has a point. The goal is to maximize the sum of the points while travelling from a starting location to a destination location without exceeding a given amount of distance.
Here is a simple example:
Starting location: C , Destination: B, Given amount of distance: 45
Solution: C-A-B route with 9 points
I'm just curious if there is some kind of dynamic algorithm for this type of problem. What the would be the best, or rather easiest approach for that problem?
Any help is greatly appreciated.
Edit: You are not allowed to visit the same location many times.
EDIT: Under the newly added restriction that every node can be visited only once, the problem is most definitely NP-hard via reduction to Hamilton path: For a general undirected, unweighted graph, set all edge weights to zero and every vertex weight to 1. Then the maximum reachable score is n iif there is a Hamilton path in the original graph.
So it might be a good idea to look into integer linear programming solvers for instance families that are not constructed specifically to be hard.
The solution below assumes that a vertex can be visited more than once and makes use of the fact that node weights are bounded by a constant.
Let p(x) be the point value for vertex x and w(x,y) be the distance weight of the edge {x,y} or w(x,y) = ∞ if x and y are not adjacent.
If we are allowed to visit a vertex multiple times and if we can assume that p(x) <= C for some constant C, we might get away with the following recurrence: Let f(x,y,P) be the minimum distance we need to get from x to y while collecting P points. We have
f(x,y,P) = ∞ for all P < 0
f(x,x,p(x)) = 0 for all x
f(x,y,P) = MIN(z, w(x, z) + f(z, y, P - p(x)))
We can compute f using dynamic programming. Now we just need to find the largest P such that
f(start, end, P) <= distance upper bound
This P is the solution.
The complexity of this algorithm with a naive implementation is O(n^4 * C). If the graph is sparse, we can get O(n^2 * m * C) by using adjacency lists for the MIN aggregation.
I have an undirected graph. For now, assume that the graph is complete. Each node has a certain value associated with it. All edges have a positive weight.
I want to find a path between any 2 given nodes such that the sum of the values associated with the path nodes is maximum while at the same time the path length is within a given threshold value.
The solution should be "global", meaning that the path obtained should be optimal among all possible paths. I tried a linear programming approach but am not able to formulate it correctly.
Any suggestions or a different method of solving would be of great help.
Thanks!
If you looking for an algorithm in general graph, your problem is NP-Complete, Assume path length threshold is n-1, and each vertex has value 1, If you find the solution for your problem, you can say given graph has Hamiltonian path or not. In fact If your maximized vertex size path has value n, then you have a Hamiltonian path. I think you can use something like Held-Karp relaxation, for finding good solution.
This might not be perfect, but if the threshold value (T) is small enough, there's a simple algorithm that runs in O(n^3 T^2). It's a small modification of Floyd-Warshall.
d = int array with size n x n x (T + 1)
initialize all d[i][j][k] to -infty
for i in nodes:
d[i][i][0] = value[i]
for e:(u, v) in edges:
d[u][v][w(e)] = value[u] + value[v]
for t in 1 .. T
for k in nodes:
for t' in 1..t-1:
for i in nodes:
for j in nodes:
d[i][j][t] = max(d[i][j][t],
d[i][k][t'] + d[k][j][t-t'] - value[k])
The result is the pair (i, j) with the maximum d[i][j][t] for all t in 0..T
EDIT: this assumes that the paths are allowed to be not simple, they can contain cycles.
EDIT2: This also assumes that if a node appears more than once in a path, it will be counted more than once. This is apparently not what OP wanted!
Integer program (this may be a good idea or maybe not):
For each vertex v, let xv be 1 if vertex v is visited and 0 otherwise. For each arc a, let ya be the number of times arc a is used. Let s be the source and t be the destination. The objective is
maximize ∑v value(v) xv .
The constraints are
∑a value(a) ya ≤ threshold
∀v, ∑a has head v ya - ∑a has tail v ya = {-1 if v = s; 1 if v = t; 0 otherwise (conserve flow)
∀v ≠ x, xv ≤ ∑a has head v ya (must enter a vertex to visit)
∀v, xv ≤ 1 (visit each vertex at most once)
∀v ∉ {s, t}, ∀cuts S that separate vertex v from {s, t}, xv ≤ ∑a such that tail(a) ∉ S ∧ head(a) ∈ S ya (benefit only from vertices not on isolated loops).
To solve, do branch and bound with the relaxation values. Unfortunately, the last group of constraints are exponential in number, so when you're solving the relaxed dual, you'll need to generate columns. Typically for connectivity problems, this means using a min-cut algorithm repeatedly to find a cut worth enforcing. Good luck!
If you just add the weight of a node to the weights of its outgoing edges you can forget about the node weights. Then you can use any of the standard algorigthms for the shortest path problem.