-1

I have a Depth Limited Search algorithm that I run several times in a loop so that the algorithm can act like an Iterative Deepening Search algorithm, Why does the code return the desired result only when I call the method explicitly but not when I call it in the loop.

public class DepthLimited {

public static void main(String[] args) {
    Graph graph = new Graph();
    graph.addNode('A');    // Since A is the first vertex so it takes the index 0  
    graph.addNode('E');    // B is the second one so it takes index 1
    graph.addNode('B');    // index 2
    graph.addNode('C');    // index 3
    graph.addNode('D');    // index 4

    graph.addEdge(0, 1);     // This indicates the relation between the vertices A and E
    graph.addEdge(1, 2);     // This indicates the relation between the vertices E and B
    graph.addEdge(0, 3);     // This indicates the relation between the vertices A and C
    graph.addEdge(3, 4);     // This indicates the relation between the vertices C and D

 //        System.out.print("Sequence: ");
 //        graph.dls(2);
 //        System.out.println("");

    graph.dls(2); // produces AEBCD when called like this, before any other similar calls i.e graph.dls(1)

    for (int i = 0; i <= 2; i++) {
        graph.dls(i);  // when i is 2 the method only returns A instead of AEBCD
        System.out.println("");
    }
}
}

And here's my Graph class:

public class Graph {

private final int MAX_NODES = 20;      //maximum number of nodes
private Node[] listOfNodes;        // list of nodes
private int neighbourMatrix[][];      // every node with its children
private int noOfNodes;              // current number of nodes
private Stack stack;

private int depth = 0;


public Graph() {
    listOfNodes = new Node[MAX_NODES];
    neighbourMatrix = new int[MAX_NODES][MAX_NODES];
    stack = new Stack();
}

public void addNode(char name) {
    listOfNodes[noOfNodes++] = new Node(name);        //create a new node and add it to the array of nodes
}

public void addEdge(int start, int end) {                //creates a bidirectional relation between
    neighbourMatrix[start][end] = 1;                     //the two nodes (start and end)
    neighbourMatrix[end][start] = 1;                     // 1 is used to indicate the existence of a relation between
}                                                        //two node because by default neighbourMatrix contains only 0s.

public void display(int node) {
    System.out.print(listOfNodes[node].name);          //prints the name of a node
}

public void dls(int limit) {                                 // begin at node 0 which is the root of the tree

    listOfNodes[0].checked = true;  // mark it
    display(0);                 // display it
    stack.push(0);                 // push it to the stack
    depth++;

    while (!stack.isEmpty()) // until stack empty,
    {
        int node = getUnvisitedChild(stack.peek());
        if (depth <= limit) {
            // get an unvisited child of the node that is at the top of the stack

            if (node == -1) // if the node had no unvisited child, then pop the node from the stack
            {
                stack.pop();
                depth--;
            } else // if the node has unvisited child         
            {
                listOfNodes[node].checked = true;  // mark it
                display(node);                 // display it
                stack.push(node);                 // push it to the stack
                depth++;
            }
        } else {
            stack.pop();
            depth--;
        }
    }
}

public int getUnvisitedChild(int v) // returns an unvisited child of the node v 
{
    for (int j = 0; j < noOfNodes; j++) {
        if (neighbourMatrix[v][j] == 1 && listOfNodes[j].checked == false) {
            return j;               //returns the index of the child
        }
    }
    return -1;              //otherwise it returns -1
}
}
Django
  • 135
  • 1
  • 2
  • 16
  • [What is a debugger and how can it help me diagnose problems?](http://stackoverflow.com/q/25385173/5221149) – Andreas May 14 '17 at 20:10
  • If `dls()` is supposed to be iterative, and it prints the vertices *as they are searched*, why would/should it print anything at all, if you *continue* a search that has already been completed? Seems you need to rethink your logic and/or your expected outcome. – Andreas May 14 '17 at 20:12

1 Answers1

0

The reason is two fold.

First, the checked value of each visited Node is set to true after dls(int limit) is called, and will remain so in subsequent calls to the method. You first need to set them to set checked back to false.

Second, depth is a class member variable/field and isn't reset to 0 each time. This variable should be local to the method.

I'd advise that you do not store whether they are visited as a property of the Node, but rather introduce a local Set (e.g. HashSet) that stores visited nodes; or in your case the integer values representing the index of the visited Node Objects.

For example, quickly hacking at your solution:

public void dls(int limit) {
    Set<Integer> visited = new HashSet<>();
    int start = 0;
    stack.push(start);
    display(start);
    int depth = 1;
    while (!stack.isEmpty()) {
        int current = stack.peek();
        visited.add(current);
        int next = -1;
        for (int adj = 0; adj < noOfNodes; adj++) {
            if (neighbourMatrix[current][adj] == 1 && !visited.contains(adj)) {
                next = adj;
            }
        }
        if (depth <= limit) {
            if (next == -1) {
                stack.pop();
                depth--;
            } else {
                stack.push(next);
                display(next);
                depth++;
            }
        } else {
            stack.pop();
            depth--;
        }
    }
}
d.j.brown
  • 1,822
  • 1
  • 12
  • 14