problems with eulerian cycle in a directed graph

829 Views Asked by At

so below is my code for finding if a graph has a eulerian cycle in a directed graph. The code works for several case(the commented lines in my main method works). But it does work for the g1 graph(the uncommented code in my main method) . it says the the graph (g1) does not that an eulerian circuit, which is should.Please help me find out the bug, thanks

  import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;


public class EulerianCirlsDirected {

        int v;
        Set<Integer> visitedDFS;
        int in[];
        HashMap<Integer,List<Integer>> adjList;
        public EulerianCirlsDirected(int v){
            this.visitedDFS = new HashSet<Integer>();
            this.adjList = new HashMap<Integer,List<Integer>>();
            this.v = v;
            in = new int[v];
        }

        //add edge
        public void addEdge(int src, int dest){
            List<Integer> srcNeighbour = this.adjList.get(src);
            if(srcNeighbour == null){
                this.adjList.put(src, srcNeighbour = new ArrayList<Integer>());
            }
            srcNeighbour.add(dest);
            in[dest]++;
        }


        //get neighbours of vertex
        public Iterable<Integer> getNeighbours(Integer vertex){

            List<Integer> neighbours = this.adjList.get(vertex);
            if(neighbours == null){
                return Collections.emptyList();
            }
            else{
                return Collections.unmodifiableList(neighbours);
            }

        }

        public int sizeNeighbours(Integer vertex){

            List<Integer> list = (List<Integer>) this.getNeighbours(vertex);


            return list.size();
        }

        //depth first search
        public Iterable<Integer> DFS(Integer src){
            Stack<Integer> stack= new Stack<Integer>();
            List<Integer> paths = new ArrayList<Integer>();
            stack.add(src);
            visitedDFS.add(src);
            paths.add(src);

            while(!stack.isEmpty()){

                int ref = stack.pop();
                for(int neig : this.getNeighbours(ref)){
                    if(!visitedDFS.contains(neig)){
                        stack.add(neig);
                        visitedDFS.add(neig);
                        paths.add(neig);
                    }
                }


            }

            return Collections.unmodifiableSet(visitedDFS);
        }

        public int numVertices(){
            return this.v;
        }

        //transpose of graph
        public EulerianCirlsDirected getTranspose(){

            int v = this.numVertices();
            EulerianCirlsDirected gr = new EulerianCirlsDirected(v);
            for(int i=0; i<v;i++){
                for(int neig:this.getNeighbours(i)){
                    gr.addEdge(neig, i);
                }
            }
            return gr;

        }

        //checks if graph has a eulerian cycle
        public boolean isEulerianCycle(){
            int v = this.numVertices();

            //check if graph is connect
            //that is every non zero degree vertex is part 
            //of a strongly connected component
            if(!isConnected()){
                return false;
            }

            //check for indegree and out degree
            for(int i=0;i<v;i++){
                if(in[i] != this.adjList.get(i).size()){
                    return false;
                }
            }

            return true;

        }

        //method to verify for strongly connected component
        public boolean isConnected(){

            int v =this.numVertices();
            int i;

            //get the first non zero degre vertex
            for( i=0; i<v;i++){
                if(this.sizeNeighbours(i)>0){break;}
            }

            //first run dfs for original graph at the first non
            //zero degree vertex
            this.DFS(i);

            //check if all vertices where visited during dfs
            for(int j=0;j<v;j++){
                if(!visitedDFS.contains(j)){
                    System.out.println("first " +visitedDFS.contains(j));
                    return false;
                }

            }

            //get transpose of graph and run dfs
            //so we have to reset visitedDFS
            visitedDFS.clear();
            EulerianCirlsDirected gr = this.getTranspose();

            //update visitedDFS to be that of the 
            //transpose
            visitedDFS= (Set<Integer>) gr.DFS(i);

            //check again if all vertices are visited in the 
            //transposed graph

            int grV = gr.numVertices();
            for(int j=0;j<grV;j++){
                if(!visitedDFS.contains(j)){
                    return false;
                }

            }
            return true;

        }
        public static void main(String[]args){

    //          EulerianCirlsDirected g = new EulerianCirlsDirected(2);
    //          g.addEdge(0, 1);
    //          g.addEdge(1, 0);
    //          g.addEdge(2, 3);
    //          g.addEdge(3, 0);
    //          g.addEdge(2, 4);
    //          g.addEdge(4, 2);

            EulerianCirlsDirected g1 = new EulerianCirlsDirected(26);
            g1.addEdge(6, 10);
            g1.addEdge(10, 6);
            System.out.println(g1.isEulerianCycle());
            //System.out.println(g.sizeNeighbours(1));

        }

    }

the output is false. please help

1

There are 1 best solutions below

2
Misha On BEST ANSWER

When you construct EulerianCirlsDirected with 26, your code expects that there will be 26 vertices and that they will all be touched by DFS.

Replace

EulerianCirlsDirected g1 = new EulerianCirlsDirected(26);
g1.addEdge(6, 10);
g1.addEdge(10, 6);

with

EulerianCirlsDirected g1 = new EulerianCirlsDirected(2);
g1.addEdge(0, 1);
g1.addEdge(1, 0);

and it will work.

Alternatively, check for this.sizeNeighbours(i) > 0 every time you iterate from 0 to v. Twice in isConnected() and once in isEurlerianCycle()