1

我最近一直在开发一个类来查看给定的无向图有一个哈密顿循环。我发现了这篇有趣的文章
http://www.geeksforgeeks.org/backtracking-set-7-hamiltonian-cycle/

我已经相应地开发了我的代码。但问题是算法无法返回哈密尔顿循环。

图.java

package graph;

public class Graph {

    private static Map<String, Vertex> vertices = new HashMap<String, Vertex> ();
    public static Map<String, LinkedList<Edges>> vertexs = new HashMap<String, LinkedList<Edges>>();
    private static Vector<Vertex> verticesID =new Vector<Vertex>();
    private static Vector<String> verticesIDString =new Vector<String>();

    public Graph(String fileName) {
        // TODO Auto-generated constructor stub
        this.LoadGraph(fileName);
    }

    public int addVertex(String ID){
        if (vertices.containsKey(ID)) 
            return -1;
        Vertex vertex=new Vertex(ID);
        vertices.put(ID, vertex);
        LinkedList<Edges> node =new LinkedList<Edges>();
        vertexs.put(ID, node);
        return 1;
    }

    public int addEdge(String from, String to, double weight){
        //check whether the vertices exist or not
        if (vertices.containsKey(from) && vertices.containsKey(to)){
            vertices.get(from).addEdge(to, weight);
            Edges newEdge = new Edges(from,to,weight);
            if(vertexs.get(from) == null)
            {
                vertexs.put(from, new LinkedList<Edges>());
            }
            vertexs.get(from).add(newEdge);
            return 1;
        }
        else{
            System.err.println ("'From' vertex and/or 'to' vertex dosen't exist! ");
            return -1;
        }
    }

    private int LoadGraph(String fileName) {
        File f;
        BufferedReader in;
        try {
            f = new File(fileName);
            in = new BufferedReader(new FileReader(f));
            String delim = "[ ]+";
            //String delim = "\t";
            String from; String to;double weight;
            int cnt = 0;
            String line = in.readLine();
            //System.out.println(line);
            while (line != null) {
                //String[] tokens=line.split(delim);
                String[] tokens=line.split(delim,-1);
                //if there're less than three entries (from,to, weight) then report err
                if (tokens.length<3){
                    System.err.println ("Invalid line format. Line should be formated as: from to weight");
                    in.close();
                    return -1;
                }
                from=tokens[0];
                to=tokens[1];
                weight=Double.parseDouble(tokens[2]);
                //first create the "from" vertex if it's not already created
                this.addVertex(from);
                //Then create the "to" vertex if it's not already created
                this.addVertex(to);
                //now associate the "from" vertex with "to" vertex using "weight"
                this.addEdge(from, to,weight);
                //do the association the other way around, i.e. force graph to be undirected.
                this.addEdge(to, from,weight);

                //if the "from" vertex is a new one, add it to the key vector
                if (!verticesIDString.contains(from)) {
                    verticesIDString.add(from);
                    verticesID.add(new Vertex(from));
                }
                //if the "to" vertex is a new one, add it to the key vector
                if (!verticesIDString.contains(to)) {
                    verticesIDString.add(to);
                    verticesID.add(new Vertex(to));
                }               
                cnt++;
                line = in.readLine();
                //System.out.println(line);
            }
            in.close();
            System.out.println(vertices.size());
            System.out.println("Successfully added "+cnt+" associations");
            return cnt;

        } catch (IOException exc) {
            System.err.println(exc.toString());
            return -1;
        }
    }

    public static ArrayList<Edges> getChildNodes(String node) 
        {
           LinkedList<Edges> neighboursList;
            Set<String> keys = vertexs.keySet();
            for (String key : keys) 
            {
                if (key.equals(node)) 
                {
                    neighboursList = vertexs.get(key);
                    return new ArrayList<Edges>(neighboursList);
                }
            }
            return new ArrayList<Edges>();
        }

    public Vertex getVertex(String ID){
        return vertices.get(ID);
    }

    public static int getVerticesCount(){
        return verticesID.size();
    }
    public static Vertex getVertexIdByIndex(int idx){
        return verticesID.elementAt(idx);
    }


    public Vector<String> BFS(String start){
        //Vector<String> tour = new Vector<String>();
        Vector<String> visited = new Vector<String>();
        LinkedList<String> queue = new LinkedList<String>();
        visited.add(start);
        queue.add(start);
        while(queue.size() != 0){
            String s = queue.poll();
            //tour.add(s);
            ArrayList<Edges> al = getChildNodes(s);
            Iterator<Edges> i = al.listIterator();
            while (i.hasNext())
            {
                String n = i.next().toVertex();
                if (!visited.contains(n))
                {
                    visited.add(n);
                    queue.add(n);
                }
            }
        }
        return visited;

    }
}

Hamiltoninan.java

package graph;

public class HamiltonianCycle {

    public Vector<String> findHamiltonianCycle(Graph g,String start){
        Vector<String> allVertex = g.BFS(start);  //this will help us with all the vertices in the graph
        Vector<String> path = new Vector<String>(); // To store the hamiltonian path
        /*Initialize the path with null at first*/
        for(int i=0;i < allVertex.size();i++){
            path.add(null);
        }
        path.add(start); // add the start as the first vertex of the hamiltonian path
        /**
         *now the recursive functions 
         *cycle problem 
         **/
        if (hamCycleUtil(g, path,allVertex) == false)
        {
            System.out.println("\nSolution does not exist");
            return null;
        }
        return path;

    }
    //The utility function tha recursively finds the hamiltonian cycle
    private boolean hamCycleUtil(Graph g, Vector<String> path,Vector<String> vers) {
        // TODO Auto-generated method stub
        if(path.size() == Graph.getVerticesCount()){
            String s1 = path.lastElement();
            ArrayList<Edges> LastNodeEdges = Graph.getChildNodes(s1);

            for(Edges Node : LastNodeEdges){
                if(Node.toVertex().equals(path.firstElement())){
                    System.out.println(path);
                    return true;
                }
            }
            return false;
        }

        for(int i=1;i<vers.size();i++){
            if(isSafe(vers.elementAt(i),g,path)){
                path.add(vers.elementAt(i));
                if(hamCycleUtil(g, path, vers) == true){
                    return true;
                }
            }
        }
        return false;
    }

    private boolean isSafe(String elementAt, Graph g, Vector<String> path) {
        // TODO Auto-generated method stub
        if(path.contains(elementAt)){
            return false;
        }
        return true;
    }   
}

有人可以指出问题出在哪里以及如何解决问题。

谢谢,卡尔蒂。

4

0 回答 0