Finding all hamiltonian cycles
Asked Answered
R

1

3

I'm trying to implement a method for adding all possible Hamiltonian cycles to a list using recursion. So far my stopping condition isn't sufficient and I get "OutOfMemoryError: Java heap space" in the line that adds a vertex to a list:

private boolean getHamiltonianCycles(int first, int v, int[] parent,
        boolean[] isVisited, List<List<Integer>> cycles) {
    isVisited[v] = true;
    if (allVisited(isVisited) && neighbors.get(v).contains(new Integer(first))) {
        ArrayList<Integer> cycle = new ArrayList<>();
        int vertex = v;
        while (vertex != -1) {
            cycle.add(vertex);
            vertex = parent[vertex];
        }
        cycles.add(cycle);
        return true;
    } else if (allVisited(isVisited)) {
        isVisited[v] = false;
        return false;
    }
    boolean cycleExists = false;
    for (int i = 0; i < neighbors.get(v).size(); i++) {
        int u = neighbors.get(v).get(i);
        parent[u] = v;
        if (!isVisited[u]
                && getHamiltonianCycles(first, u, parent, isVisited, cycles)) {
            cycleExists = true;
        }
    }
    //if (!cycleExists) {
        isVisited[v] = false; // Backtrack
    //}
    return cycleExists;
}

Can someone please suggest me what I'm doing wrong or is my approach completely incorrect?

EDIT: As suggested in comments, the culprit was the parent array, causing an infinite loop. I wasn't able to correct it and I changed the array to store the child element. Now everything seems to work:

private boolean getHamiltonianCycles(int first, int v, int[] next,
        boolean[] isVisited, List<List<Integer>> cycles) {
    isVisited[v] = true;
    if (allVisited(isVisited) && neighbors.get(v).contains(first)) {
        ArrayList<Integer> cycle = new ArrayList<>();
        int vertex = first;
        while (vertex != -1) {
            cycle.add(vertex);
            vertex = next[vertex];
        }
        cycles.add(cycle);
        isVisited[v] = false;
        return true;
    }
    boolean cycleExists = false;
    for (int u : neighbors.get(v)) {
        next[v] = u;
        if (!isVisited[u]
                && getHamiltonianCycles(first, u, next, isVisited, cycles)) {
            cycleExists = true;
        }
    }

    next[v] = -1;
    isVisited[v] = false; // Backtrack
    return cycleExists;
}
Rockie answered 20/4, 2013 at 2:35 Comment(2)
Are you sure that there always exists an reachable element in parent that equals -1?Adorno
What are the parameters of your external call for this method? Have you tried to run it the entire code under debugger?Stitch
V
2

If you is looking for Disjoint Hamiltonian Cycles here have an implementation using Backtracking.

Vespasian answered 8/6, 2013 at 18:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.