0

The difference between this question and already answered question is in the implementation. I am using recursion, and also an ArrayList of an ArrayList.

I am currently working on printing an eulerian cycle from a graph but am running into some issues. The idea is to start from a given node, go to one if its neighbors, check if its a bridge node or not, then remove the edge from the 2 nodes if it is not. By removing the edges each occurrence I will end up with my expected results. The problem is removing the edge (I think) from the adjacency list. I'm really stumped on how to get around this issue. My first thought was to just pass each function a new ArrayList instead of accessing the instance variable each pass/recurse, but it did not solve the issue. Here's an example of an input and expected output.

Starting a node 3 with the following adjacency list:

0 -> 3
1 -> 0
2 -> 1,6
3 -> 2
4 -> 2
5 -> 4
6 -> 5,8
7 -> 9
8 -> 7
9 -> 6

The output should look like:

3 -> 2 -> 6-> 8-> 7-> 9-> 6-> 5-> 4-> 2-> 1-> 0-> 3

You should start and end at the same node.

Here is my code.

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.*;

public class EU {
    static File inputFile = new File(filepath);
    int totalNodes;
    Vector<String> nodeList;
    List<ArrayList<Integer>> adjList;
    private ArrayList<Integer>[] adj;
    ArrayList<String> visited;

    private void addEdge(int u, int v)
    {
        adj[u].add((Integer) v);
    }

    // This function removes edge u-v from graph.
    private ArrayList<Integer>[] removeEdge(int u, int v)
    {
        adj[u].remove((Integer) v);
        return adj;
    }

    private EU() throws IOException {
        totalNodes = 0;
        visited = new ArrayList<>();
        adjList = new ArrayList<>();
        nodeList = new Vector<>();
        Scanner l = new Scanner(Path.of(inputFile.toURI()));
        Scanner b = new Scanner(Path.of(inputFile.toURI()));
        while(l.hasNext()){
            String in1 = l.nextLine();
            totalNodes++;
        }
        adj = new ArrayList[totalNodes];
        for(int i = 0; i < totalNodes; i++){
            adj[i] = new ArrayList<>();
        }
        while(b.hasNext()){
            String in = b.nextLine();
            String[] node = in.split(" -> ", 2 );
            String[] neighbors = node[1].split(",", node[1].length());
            for(int i = 0; i < neighbors.length; i++){
                addEdge(Integer.parseInt(node[0]), Integer.parseInt(neighbors[i]));
            }
        }
    }

    private boolean isValidNextEdge(Integer u, Integer v,ArrayList<Integer>[] ad )
    {
        // The edge u-v is valid in one of the
        // following two cases:

        // 1) If v is the only adjacent vertex of u
        // ie size of adjacent vertex list is 1
        if (ad[u].size() == 1) {
            return true;
        }

        // 2) If there are multiple adjacents, then
        // u-v is not a bridge Do following steps
        // to check if u-v is a bridge
        // 2.a) count of vertices reachable from u
        boolean[] isVisited = new boolean[totalNodes];
        int count1 = dfsCount(u, isVisited, ad);

        // 2.b) Remove edge (u, v) and after removing
        // the edge, count vertices reachable from u
        isVisited = new boolean[totalNodes];
        int count2 = dfsCount(v, isVisited, removeEdge(u, v));

        // 2.c) Add the edge back to the graph
        addEdge(u, v);
        return count1 <= count2;
    }

    private int dfsCount(Integer v, boolean[] isVisited,ArrayList<Integer>[] ad )
    {
        // Mark the current node as visited
        isVisited[v] = true;
        int count = 1;
        // Recur for all vertices adjacent to this vertex
        for (int a : ad[v]) {
            if (!isVisited[a]) {
                count = count + dfsCount(a, isVisited, ad);
            }
        }
        return count;
    }

    public void printe(int u, ArrayList<Integer>[] ad){
        ArrayList<Integer> list = new ArrayList<>();
        for (int i = 0; i < ad[u].size(); i++) {
            list = ad[u];
            // If edge u-v is a valid next edge
            for(Integer neighbors : list) {
                if (isValidNextEdge(u, neighbors, ad)) {
                    System.out.print(u + "-" + neighbors + " ");

                    // This edge is used so remove it now
                    removeEdge(u, neighbors);
                    printe(neighbors, removeEdge(u, neighbors));
                }
            }
        }
    }

    public static void main(String[] args) throws IOException {
        EU r = new EU();
        int in = r.adj[0].get(0);
        r.printe(in, r.adj);
    }
}
Abra
  • 19,142
  • 7
  • 29
  • 41
bdunaway
  • 33
  • 5
  • You can ignore the initialization process, adj. list is coming from a file – bdunaway Oct 08 '22 at 19:33
  • 1
    The fact you're using recursion and array list of array lists is not relevant. What is relevant is that you are iterating over the array list and then structurally modifying it. – Mark Rotteveel Oct 10 '22 at 09:50
  • Please don't use the `Vector` class. I'd also strongly discourage using something akin to `List[]` barring very few circumstances. – Rogue Oct 10 '22 at 16:48

0 Answers0