Open In App

Karp’s minimum mean (or average) weight cycle algorithm

Last Updated : 20 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a directed and strongly connected graph with non-negative edge weights. We define the 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 Graph

karps_mean_value

Output : 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 to the solution of problem 9.2 here for proof that the above steps find minimum average weight.

Implementation:

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 itself 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;
}


Java




// Java program to find minimum average
// weight of a cycle in connected and
// directed graph.
import java.io.*;
import java.util.*;
 
class GFG
{
static int V = 4;
 
// a struct to represent edges
static class Edge
{
    int from, weight;
 
    Edge(int from, int weight)
    {
        this.from = from;
        this.weight = weight;
    }
}
 
// vector to store edges
//@SuppressWarnings("unchecked")
static Vector<Edge>[] edges = new Vector[V];
static
{
    for (int i = 0; i < V; i++)
        edges[i] = new Vector<>();
}
 
static void addedge(int u, int v, int w)
{
    edges[v].add(new Edge(u, w));
}
 
// calculates the shortest path
static void shortestpath(int[][] dp)
{
    // 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 itself 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].elementAt(k).from] != -1)
                {
                    int curr_wt = dp[i - 1][edges[j].elementAt(k).from] +
                                            edges[j].elementAt(k).weight;
                    if (dp[i][j] == -1)
                        dp[i][j] = curr_wt;
                    else
                        dp[i][j] = Math.min(dp[i][j], curr_wt);
                }
            }
        }
    }
}
 
// Returns minimum value of average weight
// of a cycle in graph.
static double minAvgWeight()
{
    int[][] dp = new int[V + 1][V];
    shortestpath(dp);
 
    // array to store the avg values
    double[] avg = new double[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] = Math.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 Code
public static void main(String[] args)
{
    addedge(0, 1, 1);
    addedge(0, 2, 10);
    addedge(1, 2, 3);
    addedge(2, 3, 2);
    addedge(3, 1, 0);
    addedge(3, 0, 8);
 
    System.out.printf("%.5f", minAvgWeight());
}
}
 
// This code is contributed by
// sanjeev2552


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 itself 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


C#




// C# program to find minimum
// average weight of a cycle
// in connected and directed graph.
using System;
using System.Collections.Generic;
class GFG{
   
static int V = 4;
 
// a struct to represent
// edges
public class Edge
{
  public int from, weight;
  public Edge(int from,
              int weight)
  {
    this.from = from;
    this.weight = weight;
  }
}
 
// vector to store edges 
static List<Edge>[] edges =
            new List<Edge>[V]; 
 
static void addedge(int u,
                    int v, int w)
{
  edges[v].Add(new Edge(u, w));
}
 
// calculates the shortest path
static void shortestpath(int[,] dp)
{
  // 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 itself
  // 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].Count; 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] = Math.Min(dp[i, j],
                                curr_wt);
        }
      }
    }
  }
}
 
// Returns minimum value of
// average weight of a cycle
// in graph.
static double minAvgWeight()
{
  int[,] dp = new int[V + 1, V];
  shortestpath(dp);
 
  // array to store the
  // avg values
  double[] avg = new double[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] = Math.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 Code
public static void Main(String[] args)
{
  for (int i = 0; i < V; i++)
    edges[i] = new List<Edge>();
   
  addedge(0, 1, 1);
  addedge(0, 2, 10);
  addedge(1, 2, 3);
  addedge(2, 3, 2);
  addedge(3, 1, 0);
  addedge(3, 0, 8);
 
  Console.Write("{0:F5}",
                minAvgWeight());
}
}
 
// This code is contributed by Princi Singh


Javascript




<script>
 
// JavaScript program to find minimum
// average weight of a cycle
// in connected and directed graph.
   
var V = 4;
 
// a struct to represent
// edges
class Edge
{
    constructor(from, weight)
    {
        this.from = from;
        this.weight = weight;
    }
}
 
// vector to store edges 
var edges = Array.from(Array(V), ()=>Array());
 
function addedge(u, v, w)
{
  edges[v].push(new Edge(u, w));
}
 
// calculates the shortest path
function shortestpath(dp)
{
  // initializing all distances
  // as -1
  for (var i = 0; i <= V; i++)
    for (var j = 0; j < V; j++)
      dp[i][j] = -1;
 
  // shortest distance from
  // first vertex to in itself
  // consisting of 0 edges
  dp[0][0] = 0;
 
  // filling up the dp table
  for (var i = 1; i <= V; i++)
  {
    for (var j = 0; j < V; j++)
    {
      for (var k = 0;
               k < edges[j].length; k++)
      {
        if (dp[i - 1][
               edges[j][k].from] != -1)
        {
          var 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] = Math.min(dp[i][j],
                                curr_wt);
        }
      }
    }
  }
}
 
// Returns minimum value of
// average weight of a cycle
// in graph.
function minAvgWeight()
{
  var dp = Array.from(Array(V+1), ()=>Array(V).fill(0))
  shortestpath(dp);
 
  // array to store the
  // avg values
  var avg = Array(V).fill(0);
   
  for (var i = 0; i < V; i++)
    avg[i] = -1;
 
  // Compute average values for
  // all vertices using weights
  // of shortest paths store in dp.
  for (var i = 0; i < V; i++)
  {
    if (dp[V][i] != -1)
    {
      for (var j = 0; j < V; j++)
        if (dp[j][i] != -1)
          avg[i] = Math.max(avg[i],
                           ( dp[V][i] -
                             dp[j][i]) /
                             (V - j));
    }
  }
 
  // Find minimum value in avg[]
  var result = avg[0];
   
  for (var i = 0; i < V; i++)
    if (avg[i] != -1 &&
        avg[i] < result)
      result = avg[i];
 
  return result;
}
 
// Driver Code
addedge(0, 1, 1);
addedge(0, 2, 10);
addedge(1, 2, 3);
addedge(2, 3, 2);
addedge(3, 1, 0);
addedge(3, 0, 8);
document.write(minAvgWeight().toFixed(5));
 
 
</script>


Output

1.66667

Here the graph with no cycle will return value as -1.

Time Complexity : The time complexity of the given program is O(V^3), where V is the number of vertices in the graph. This is because the program uses a nested loop to fill up the dp table, and the size of the dp table is V^2. The outermost loop runs V times, the middle loop runs V times, and the innermost loop can run up to V times in the worst case, giving a total time complexity of O(V^3). The other parts of the program have a lower time complexity and do not contribute significantly to the overall time complexity.

Space Complexity : The space complexity of the given  program is O(V^2), where V is the number of vertices in the graph. This is because the program creates a 2D array dp of size (V+1)xV, which requires O(V^2) space. Additionally, the program creates a vector of edges, which takes up O(E) space, where E is the number of edges in the graph. However, in this particular implementation, the number of edges is not directly stored, and it is not clear whether all edges are actually added to the vector. Therefore, the space complexity is mainly determined by the size of the dp array, which is O(V^2).



Previous Article
Next Article

Similar Reads

Hopcroft–Karp Algorithm for Maximum Matching | Set 1 (Introduction)
A matching in a Bipartite Graph is a set of the edges chosen in such a way that no two edges share an endpoint. A maximum matching is a matching of maximum size (maximum number of edges). In a maximum matching, if any edge is added to it, it is no longer a matching. There can be more than one maximum matching for a given Bipartite Graph. We have di
3 min read
Rabin-Karp algorithm for Pattern Searching in Matrix
Given matrices txt[][] of dimensions m1 x m2 and pattern pat[][] of dimensions n1 x n2, the task is to check whether a pattern exists in the matrix or not, and if yes then print the top most indices of the pat[][] in txt[][]. It is assumed that m1, m2 ? n1, n2 Examples: Input: txt[][] = {{G, H, I, P} {J, K, L, Q} {R, G, H, I} {S, J, K, L} } pat[][]
15+ min read
Implementing Rabin Karp Algorithm Using Rolling Hash in Java
There are so many pattern searching algorithms for the string. KMP algorithm, Z algorithm Rabin Karp algorithm, etc these algorithms are the optimization of Naive Pattern searching Algorithm. Naive Pattern Searching Algorithm: Input : "AABACACAACAC" Pattern : "CAC" Output : [4,9] AABACACAACAC Implementation: Java Code // Java Program to Search for
5 min read
Count distinct substrings of a string using Rabin Karp algorithm
Given a string, return the number of distinct substrings using Rabin Karp Algorithm. Examples: Input : str = “aba”Output : 5Explanation :Total number of distinct substring are 5 - "a", "ab", "aba", "b" ,"ba" Input : str = “abcd”Output : 10Explanation :Total number of distinct substring are 10 - "a", "ab", "abc", "abcd", "b", "bc", "bcd", "c", "cd",
9 min read
Rabin-Karp Algorithm for Pattern Searching
Given a text T[0. . .n-1] and a pattern P[0. . .m-1], write a function search(char P[], char T[]) that prints all occurrences of P[] present in T[] using Rabin Karp algorithm. You may assume that n &gt; m. Examples: Input: T[] = "THIS IS A TEST TEXT", P[] = "TEST"Output: Pattern found at index 10 Input: T[] = "AABAACAADAABAABA", P[] = "AABA"Output:
15 min read
Hopcroft–Karp Algorithm for Maximum Matching | Set 2 (Implementation)
We strongly recommend to refer below post as a prerequisite.Hopcroft–Karp Algorithm for Maximum Matching | Set 1 (Introduction) There are few important things to note before we start implementation. We need to find an augmenting path (A path that alternates between matching and not matching edges and has free vertices as starting and ending points)
13 min read
Hopcroft–Karp Algorithm in Python
A matching in a Bipartite Graph is a set of edges chosen in such a way that no two edges share an endpoint. A maximum matching is a matching of maximum size (maximum number of edges). In a maximum matching, if any edge is added to it, it is no longer a matching. There can be more than one maximum matching for a given Bipartite Graph. Hopcroft Karp
5 min read
Find Harmonic mean using Arithmetic mean and Geometric mean
Given two numbers, first calculate arithmetic mean and geometric mean of these two numbers. Using the arithmetic mean and geometric mean so calculated, find the harmonic mean between the two numbers. Examples: Input : a = 2 b = 4 Output : 2.666 Input : a = 5 b = 15 Output : 7.500 Arithmetic Mean: Arithmetic Mean 'AM' between two numbers a and b is
5 min read
Find minimum weight cycle in an undirected graph
Given a positive weighted undirected graph, find the minimum weight cycle in it. Examples: Minimum weighted cycle is : Minimum weighed cycle : 7 + 1 + 6 = 14 or 2 + 6 + 2 + 4 = 14 The idea is to use shortest path algorithm. We one by one remove every edge from the graph, then we find the shortest path between two corner vertices of it. We add an ed
15+ min read
Count number of paths whose weight is exactly X and has at-least one edge of weight M
Given an infinite tree and three numbers N, M, and X which has exactly N child from every node. Every edge has a weight of 1, 2, 3, 4..N. The task is to find the count of paths whose weight is exactly X and has a minimum of one edge of weight M in it. The diagram above shows a tree shown till level-3 and N = 3. Examples: Input: N = 3, M = 2, X = 3
8 min read
Practice Tags :
three90RightbarBannerImg