1

I have to implement a search algorithm in java for a school project. In this algorithm i need to find, in an undirected graph, a path that goes through each link only once and ends in the start node. I'm trying to use a DFS with backtracking to solve this problem, but i'm having trouble implementating it. Here's my code:

import java.util.*;

public class Graph {

    private Map<Integer, LinkedHashSet<Integer>> map = 
        new HashMap<Integer, LinkedHashSet<Integer>>();
    private int startNode;
    private int numLinks;



    public Graph(int startNode, int numLinks) {
        super();
        this.startNode = startNode;
        this.numLinks = numLinks;
    }

    public void addEdge(int source, int destiny) {
        LinkedHashSet<Integer> adjacente = map.get(source);
        if(adjacente==null) {
            adjacente = new LinkedHashSet<Integer>();
            map.put(source, adjacente);
        }
        adjacente.add(destiny);
    }

    public void addLink(int source, int destiny) {
        addEdge(source, destiny);
        addEdge(destiny, source);
    }

    public LinkedList<Integer> adjacentNodes(int last) {
        LinkedHashSet<Integer> adjacente = map.get(last);
        System.out.println("adjacentes:" + adjacente);
        if(adjacente==null) {
            return new LinkedList<Integer>();
        }
        return new LinkedList<Integer>(adjacente);
    }

public static void main(String[] args) {

    Scanner input = new Scanner(System.in);

    int numVertices = input.nextInt();
    int numLinks = input.nextInt();
    int startNode = input.nextInt();
    int endNode = startNode;

    Graph mapa = new Graph(startNode, numLinks);

    for(int i = 0; i<numLinks; i++){
        mapa.addLink(input.nextInt(), input.nextInt());

    }

    List<ArrayList<Integer>> paths = new ArrayList<ArrayList<Integer>>();
    Integer currentNode = startNode;
    List<Integer> visited = new ArrayList<Integer>();
    visited.add(startNode);
    mapa.findAllPaths(mapa, visited, paths, currentNode);

    for(ArrayList<Integer> path : paths){
        for (Integer node : path) {
            System.out.print(node);
            System.out.print(" ");
        }
        System.out.println();
    }

}

private void findAllPaths(Graph mapa, List<Integer> visited,
        List<ArrayList<Integer>> paths, Integer currentNode) {


    if (currentNode.equals(startNode)) { 
        paths.add(new ArrayList<Integer>(visited));
        return;
    }

    else {
        LinkedList<Integer> nodes = mapa.adjacentNodes(currentNode);    
        for (Integer node : nodes) {
            if (visited.contains(node)) {
                continue;
            } 
            List<Integer> temp = new ArrayList<Integer>();
            temp.addAll(visited);
            temp.add(node);          
            findAllPaths(mapa, temp, paths, node);
        }
    }

} 

}

The program is supposed to receive integers on his input, where the first one is the number of nodes, the second one is the number of links, the third is the start node(wich is also the end node), all the integers that come after represent the links between nodes.

The goal is to, in the end, print a single line with integers. This integers represent the order i visit each node to complete the path. Currently testing, it only prints a single integer, wich represents the first node.

I think my problem is either populating the graph, populating the adjacent list. Can somebody help me?

4
  • Please be more specific as what problems you have. What doesn't work as expected, what do you expect etc.? Commented Mar 20, 2012 at 17:07
  • My goal is to, in the end, print a single line with integers. This integers represent the order i visit each node to complete the path. Currently testing, it only prints a single integeer, wich represents the first node. Commented Mar 20, 2012 at 17:13
  • @Cláudio Ribeiro: isn't this the NP-hard Travelling salesman problem with the added requirement to return to the starting city (which doesn't change the complexity of the problem)? Do you need to find the shortest path or just any way? How many nodes at most? Commented Mar 20, 2012 at 17:21
  • I think it is that problem. The number of nodes varies from 1 to 10000. I need to find all the paths and show the one that comes first in lexicographic order. Commented Mar 20, 2012 at 17:33

2 Answers 2

1

The problem is that when you call mapa.findAllPaths(mapa, visited, paths, currentNode);, you don't actually find all paths. You only find one path (i.e. the current node) and you return:

private void findAllPaths(Graph mapa, List<Integer> visited,
        List<ArrayList<Integer>> paths, Integer currentNode) {

    if (currentNode.equals(startNode)) { 
        paths.add(new ArrayList<Integer>(visited));
        return;// <--- WRONG!!!
    } else {
        // The else is never executed!
    }
} 

You should either have a loop or recursively call the findAllPaths until you find all the paths.

Sign up to request clarification or add additional context in comments.

3 Comments

@CláudioRibeiro commenting out the return line is step 1; step 2 is to make a loop which iterates over all the nodes in the graph and add them to the paths list.
I have several questions: 1. What is the point of this "exercise"? 2. If the point is not to build your own graph, then why don't you use a 3rd party graph library?
This is a school exercise, algorithm class. I can't use any 3rd party graph library, as i can only turn in a single java file. The exercise is all about the algorithm, how we do it is up to us.
1

The first time you invoke the findAllPaths method you are passing the startNode as the last argument (the currentNode), which leads to currentNode.equals(startNode) being true and as such the only part of the method that gets executed is:

paths.add(new ArrayList<Integer>(visited));
return;

In essence, you only add the first node to your paths and then your algorithm finishes, thus always printing a single integer, the start node.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.