Given a directed and strongly connected graph with non negative edge weighs. We define mean weight of a cycle as the summation of all the edge weights of the cycle divided by the no. of edges. Our task is to find the minimum mean weight among all the directed cycles of the graph.
Example:
Input : Below GraphOutput : 1.66667
Method to find the smallest mean weight value cycle efficiently
Step 1: Choose first vertex as source. Step 2: Compute the shortest path to all other vertices on a path consisting of k edges 0 <= k <= V where V is number of vertices. This is a simple dp problem which can be computed by the recursive solution dp[k][v] = min(dp[k][v], dp[k-1][u] + weight(u,v) where v is the destination and the edge(u,v) should belong to E Step 3: For each vertex calculate max(dp[n][v]-dp[k][v])/(n-k) where 0<=k<=n-1 Step 4: The minimum of the values calculated above is the required answer.
Please refer solution of problem 9.2 here for proof that above steps find minimum average weight.
C++
// C++ program to find minimum average // weight of a cycle in connected and // directed graph. #include<bits/stdc++.h> using namespace std; const int V = 4; // a struct to represent edges struct edge { int from, weight; }; // vector to store edges vector <edge> edges[V]; void addedge( int u, int v, int w) { edges[v].push_back({u, w}); } // calculates the shortest path void shortestpath( int dp[][V]) { // initializing all distances as -1 for ( int i=0; i<=V; i++) for ( int j=0; j<V; j++) dp[i][j] = -1; // shortest distance from first vertex // to in tself consisting of 0 edges dp[0][0] = 0; // filling up the dp table for ( int i=1; i<=V; i++) { for ( int j=0; j<V; j++) { for ( int k=0; k<edges[j].size(); k++) { if (dp[i-1][edges[j][k].from] != -1) { int curr_wt = dp[i-1][edges[j][k].from] + edges[j][k].weight; if (dp[i][j] == -1) dp[i][j] = curr_wt; else dp[i][j] = min(dp[i][j], curr_wt); } } } } } // Returns minimum value of average weight of a // cycle in graph. double minAvgWeight() { int dp[V+1][V]; shortestpath(dp); // array to store the avg values double avg[V]; for ( int i=0; i<V; i++) avg[i] = -1; // Compute average values for all vertices using // weights of shortest paths store in dp. for ( int i=0; i<V; i++) { if (dp[V][i] != -1) { for ( int j=0; j<V; j++) if (dp[j][i] != -1) avg[i] = max(avg[i], (( double )dp[V][i]-dp[j][i])/(V-j)); } } // Find minimum value in avg[] double result = avg[0]; for ( int i=0; i<V; i++) if (avg[i] != -1 && avg[i] < result) result = avg[i]; return result; } // Driver function int main() { addedge(0, 1, 1); addedge(0, 2, 10); addedge(1, 2, 3); addedge(2, 3, 2); addedge(3, 1, 0); addedge(3, 0, 8); cout << minAvgWeight(); return 0; } |
Python3
# Python3 program to find minimum # average weight of a cycle in # connected and directed graph. # a struct to represent edges class edge: def __init__( self , u, w): self .From = u self .weight = w def addedge(u, v, w): edges[v].append(edge(u, w)) # calculates the shortest path def shortestpath(dp): # initializing all distances as -1 for i in range (V + 1 ): for j in range (V): dp[i][j] = - 1 # shortest distance From first vertex # to in tself consisting of 0 edges dp[ 0 ][ 0 ] = 0 # filling up the dp table for i in range ( 1 , V + 1 ): for j in range (V): for k in range ( len (edges[j])): if (dp[i - 1 ][edges[j][k].From] ! = - 1 ): curr_wt = (dp[i - 1 ][edges[j][k].From] + edges[j][k].weight) if (dp[i][j] = = - 1 ): dp[i][j] = curr_wt else : dp[i][j] = min (dp[i][j], curr_wt) # Returns minimum value of average # weight of a cycle in graph. def minAvgWeight(): dp = [[ None ] * V for i in range (V + 1 )] shortestpath(dp) # array to store the avg values avg = [ - 1 ] * V # Compute average values for all # vertices using weights of # shortest paths store in dp. for i in range (V): if (dp[V][i] ! = - 1 ): for j in range (V): if (dp[j][i] ! = - 1 ): avg[i] = max (avg[i], (dp[V][i] - dp[j][i]) / (V - j)) # Find minimum value in avg[] result = avg[ 0 ] for i in range (V): if (avg[i] ! = - 1 and avg[i] < result): result = avg[i] return result # Driver Code V = 4 # vector to store edges edges = [[] for i in range (V)] addedge( 0 , 1 , 1 ) addedge( 0 , 2 , 10 ) addedge( 1 , 2 , 3 ) addedge( 2 , 3 , 2 ) addedge( 3 , 1 , 0 ) addedge( 3 , 0 , 8 ) print (minAvgWeight()) # This code is contributed by Pranchalk |
Output:
1.66667
Here the graph with no cycle will return value as -1.
Reference:
https://courses.csail.mit.edu/6.046/fall01/handouts/ps9sol.pdf
https://www.hackerearth.com/practice/notes/karp-minimum-mean-weighted-cycle/
Introduction to Algorithms Third Edition page 681 by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest and Clifford Stein
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
leave a comment
0 Comments