有向无权图上的哈密顿路径算法使用不存在的边

时间:2019-05-28 08:44:03

标签: java algorithm hamiltonian-path

我正在尝试实现Held-Karp算法,以在未加权有向图上找到哈密顿路径。为了实现这一点,我创建了一个内部类Combination,它存储一个表示所采用路径顺序的Stack和一个Set,用于存储当前路径中的元素。

哈密顿路径的定义是仅一次

访问图形中每个顶点的路径

我还使用队列来存储该算法尚未完全探索或打折的路径。

最初,此队列填充有组合,每个组合在图中包含一个顶点。这满足了Held-Karp的基本情况,其中平凡的哈密顿路径是通过单个顶点的路径。

当队列不为空时,队列前面的元素将出队。窥视其堆栈中的顶部元素,因为该元素表示添加到路径的最后一个顶点。循环遍历最后一个顶点的相邻顶点,如果其中任何一个不在当前路径集中,则会使用先前的路径Stack和path Set创建一个新的Combination对象,并将新顶点添加到Stack和Set中。将此新的组合对象添加到队列的后面,以供以后分析。如果无法将另一个顶点添加到路径,则循环将继续,并且对该Combination对象的引用将丢失-Combination被打折。

如果在出队时遇到组合对象,且该对象的堆栈长度与图中的顶点数相同,则我们返回该堆栈的数组表示形式,因为它是哈密顿路径。

我正在针对此Graph测试此算法。

我的代码为此图形生成的邻接列表如下:

[[1], [2, 3], [4], [4], [5], []]

并且矩阵索引和顶点值之间的键映射为:

{0=F, 1=A, 2=B, 3=D, 4=C, 5=E}
    public String[] getHamiltonianPath() {
        String hamiltonianPath[] = new String[adjacencyList.size()];
        Combination newCombination;
        for(int i = 0; i < adjacencyList.size(); i++) {
            LinkedList<Combination> combinations = new LinkedList<>();
            // create base case with paths of length 1 including only a single vertex.
            for(int j = 0; j < adjacencyList.size(); j++) {
                combinations.add(new Combination(j));
            }
            while(!combinations.isEmpty()) {
                Combination current = combinations.pollFirst();
                // If we've found a Hamiltonian Path return it.
                if(current.pathOrder.size()  == adjacencyList.size()) {
                    while(!current.pathOrder.isEmpty()) {

                        hamiltonianPath[current.pathOrder.size() - 1] = ids.get(current.pathOrder.pop());
                    }
                    return(hamiltonianPath);
                }
                // Select the last vertex added to the path
                int lastVertex = current.pathOrder.peek();
                // Get all the vertices adjacent to the last vertex added to the path
                HashSet<Integer> neighbours = adjacencyList.get(lastVertex);

                for(int neighbour : neighbours) {
                    // Create a new combination for each path that includes the previous path
                    // and is extended to one of the adjacent vertices to the last vertex added.
                    newCombination = new Combination(current.path, current.pathOrder);
                    // Check if the adjacent vertex is already on the path.
                    // If so do not add it to the path
                    if(!newCombination.path.contains(neighbour)) {
                        newCombination.path.add(neighbour);
                        newCombination.pathOrder.push(neighbour);
                        // Add the new combination to the combinations queue
                        // for further extension later
                        combinations.add(newCombination);
                    }
                }
            }
        }
        return(hamiltonianPath);
    }


    public class Combination {
        HashSet<Integer> path;
        Stack<Integer> pathOrder;


        public Combination(HashSet<Integer> path, Stack<Integer> pathOrder) {
            this.path = path;
            this.pathOrder = pathOrder;
        }

        public Combination(int origin) {
            path = new HashSet<>();
            pathOrder = new Stack<>();

            path.add(origin);
            pathOrder.push(origin);
        }
    }

ids HashMap只是顶点的整数ID及其实际String值之间的映射。

由于此图不包含哈密顿路径,因此我希望输出为空字符串数组。但是我实际得到的输出是:

F-> A-> B-> D-> C-> E

这很奇怪,因为图形或矩阵中的B和D之间没有边。

0 个答案:

没有答案