Java Program to Find a Good Feedback Edge Set in a Graph


A feedback edge set in a graph refers to a set of edges that, when removed from the graph, eliminates all cycles or feedback loops. In other words, it is a subset of edges that, when deleted, transforms the original graph into a directed acyclic graph (DAG). A good feedback edge set is a feedback edge set that has the minimum possible number of edges.

In this tutorial, we will learn to find a Good Feedback Edge Set in a Graph.

Problem Statement

Write a Java program that identifies and removes feedback edges in a graph to construct a Good Feedback Edge Set. The program should take as input a graph represented by its vertices and edges. The output of the program should be the list of feedback edges or an indication if no feedback edges are found

Sample Examples

Input

Vertices (v): 3
Edges: (1, 2), (2, 3), (3, 1)

Output

Feedback Edge Set: (3, 1)

Explanation

Edge (3, 1) makes cycle in a graph. When we remove this edge, graph will become directed acyclic graph (DAG). 

Input

Vertices (v): 4
Edges: (1, 2), (2, 3), (3, 4), (4, 1), (2, 4)

Output

Feedback Edge Set: (3, 4), (4, 1)

Explanation

When we remove edges (3, 4) and (4, 1), graph will become directed acyclic graph (DAG).

Algorithm

  • Step 1 − Create a class named ‘Graph’ with a private instance variable adjacencyList of type Map> to store the graph's adjacency list.

  • Step 2 − Implement a constructor Graph(int v) that initializes the adjacency list with empty lists for each vertex from 1 to v.

  • Step 3 − Implement a method setEdge(int src, int dest) to add a new edge to the graph. If the source vertex already exists in the adjacency list, add the destination vertex to its list of neighbours. Otherwise, create a new list of neighbours and add it to the adjacency list with the source vertex as the key.

  • Step 4 − Implement a method removeSinkVertices( ) to remove all the sink vertices from the graph. Iterate over each vertex in the adjacency list and check if its list of neighbours is empty. If so, add it to the list of sink vertices. Then, remove these sink vertices and their corresponding edges from the adjacency list.

  • Step 5.1 − Implement a method hasFeedbackEdgeSet( ) to check if the graph contains a feedback edge set (a cycle). Create an array visited of size v + 1 to track visited vertices

  • Step 5.2 − Initialize a flag ‘flag’ as false. Get the set of all vertices from the adjacency list. Convert the set to a list nodeList and iterate over it.

  • Step 5.3 − For each vertex index in nodeList, get its list of neighbours. Set visited[index] as 1 to mark it as visited.

  • Step 5.4 − If the list of neighbours is not empty, iterate over each neighbour. If the neighbour has been visited before, set flag as true, indicating the presence of a feedback edge. Otherwise, mark the neighbour as visited.

  • Step 6 − Create a class named ‘Main’ with a main method. Instantiate a Graph object with the given number of vertices (v).

  • Step 6.1 − Add edges to the graph using the setEdge( ) method. Remove sink vertices from the graph using the removeSinkVertices method. Print the results.

Example

In the example code, we construct a graph, remove sink vertices, and identify feedback edges to determine if a good feedback edge set exists in the given graph.

import java.util.*;

class Graph {
   private Map<Integer, List<Integer>> adjacencyList;
   // Graph Constructor
   public Graph(int v) {
      adjacencyList = new HashMap<>();
      for (int i = 1; i <= v; i++) {
         adjacencyList.put(i, new ArrayList<>());
      }
   }
   // Adding new edge
   public void setEdge(int src, int dest) {
      if (adjacencyList.containsKey(src)) {
         // If the source vertex already exists in the adjacency list, add the destination vertex to its list of neighbors
         List<Integer> neighbors = adjacencyList.get(src);
         neighbors.add(dest);
      } else {
         List<Integer> neighbors = new ArrayList<>();
         neighbors.add(dest);
         adjacencyList.put(src, neighbors);
      }
   }
   public Graph removeSinkVertices() {
      List<Integer> sinkVertices = new ArrayList<>();
      // Find all sink vertices (vertices with no outgoing edges)
      for (Integer vertex : adjacencyList.keySet()) {
         if (adjacencyList.get(vertex).isEmpty()) {
            sinkVertices.add(vertex);
         }
      }
      // Remove sink vertices and their edges
      for (Integer sinkVertex : sinkVertices) {
         adjacencyList.remove(sinkVertex);
         for (List<Integer> edges : adjacencyList.values()) {
            edges.remove(sinkVertex);
         }
      }
      return this;
   }
   // Check if the graph contains a feedback edge set
   public boolean hasFeedbackEdgeSet() {
      int v = this.adjacencyList.size();
      boolean flag = false;
      int[] visited = new int[v + 1];
      Set<Integer> nodes = this.adjacencyList.keySet();
      List<Integer> nodeList = new ArrayList<>(nodes);
      for (int nodeIndex = 0; nodeIndex < nodeList.size(); nodeIndex++) {
         Integer index = nodeList.get(nodeIndex);
         List<Integer> neighbours = this.adjacencyList.get(index);
         visited[index] = 1;
         if (neighbours.size() != 0) {
            for (int i = 0; i < neighbours.size(); i++) {
               if (visited[neighbours.get(i)] == 1) {
                  // Found a feedback edge (cycle) in the graph
                  flag = true;
                  System.out.println(index + " -> " + neighbours.get(i));
               } else {
                  visited[neighbours.get(i)] = 1;
               }
            }
         }
      }
      return flag;
   }
}
public class Main {
   public static void main(String[] args) {
      // Number of vertices
      int v = 4;
      Graph graph = new Graph(v);
      graph.setEdge(1, 2);
      graph.setEdge(2, 3);
      graph.setEdge(3, 4);
      graph.setEdge(4, 1);
      graph.setEdge(2, 4);
      graph = graph.removeSinkVertices();
      System.out.println("Feedback Edge Set is as follows:");
      if (!graph.hasFeedbackEdgeSet()) {
         System.out.println("None");
      }
   }
}

Output

Feedback Edge Set is as follows:
3 -> 4
4 -> 1

Time Complexity: O(V*E)

Since we need to visit each vertex and each of its edges to check for feedback edges, the time complexity is proportional to the number of vertices multiplied by the average number of edges per vertex, resulting in O(v * e).

Conclusion

In conclusion, the concept of a Good Feedback Edge Set in a graph plays a crucial role in identifying and eliminating cycles or feedback loops within the graph. By removing a minimal set of edges, we can transform the original graph into a directed acyclic graph (DAG), which has various practical applications in areas such as network optimization, circuit design, and scheduling.

Updated on: 04-Jul-2023

139 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements