如何检测图形是否为哈密顿图

时间:2013-02-12 09:59:30

标签: data-structures recursion graph-algorithm

我有一个要求实现接口方法isHamiltonian的赋值问题,我尝试使用递归来解决问题。

如果存在满足条件的路径

,那么只需尝试来自节点的所有路径
  • 只运行一次所有节点
  • 最后一个节点直接连接到第一个节点

我会说这是汉密尔顿主义者。

我已尝试过这些代码,但它不起作用

public static boolean isHamiltonian(Graph g) throws InvalidGraphException {
    if (g == null || !(g instanceof GraphI) || ((GraphI) g).getDirected()) {
        throw new InvalidGraphException();
    }

    NodeI[] nodes = (NodeI[]) g.nodes();
    if (nodes.length < 3)
        return false;

    return isHamiltonian(nodes[0], nodes[0], new HashSet<NodeI>());
}

private static boolean isHamiltonian(NodeI start, NodeI n, HashSet<NodeI> hs) {
    hs.add(n);
    NodeI[] nodes = n.getReachableNeighbours();
    boolean connectedWithStart = false;
    for (int i = 0; i < nodes.length; i++) {
        if (nodes[i].compareTo(start) == 0) {
            connectedWithStart = true;
            break;
        }
    }
    if (hs.size() == n.getGraph().nodes().length && connectedWithStart) {
        return true;
    }
    for (int i = 0; i < nodes.length; i++) {
        if (!hs.contains(nodes[i]))
            isHamiltonian(start, nodes[i], hs);
    }

    return false;
}

1 个答案:

答案 0 :(得分:1)

在我看来,你的回溯就是问题所在。您贪婪地向hs添加节点以构建路径,但是当您未能完成循环/没有任何方法时,您不会删除它们。

我要做的第一件事是将hs.remove(n)放在最后的return false之前。然后我还会保存isHamiltonian(start,nodes[i],hs)的结果并在它为真时退出。像这样的东西

boolean result = isHamiltonian(start,nodes[i],hs);
if(result)return true;`

这应该解决很多问题。我确实认为这种详尽的搜索会很慢。

编辑:整件事应该是这样的:

private static boolean isHamiltonian(NodeI start, NodeI n, HashSet<NodeI> hs) {
    hs.add(n);
    NodeI[] nodes = n.getReachableNeighbours();
    boolean connectedWithStart = false;
    for (int i = 0; i < nodes.length; i++) {
        if (nodes[i].compareTo(start) == 0) {
            connectedWithStart = true;
            break;
        }
    }
    if (hs.size() == n.getGraph().nodes().length && connectedWithStart) {
        return true;
    }
    for (int i = 0; i < nodes.length; i++) {
        if (!hs.contains(nodes[i])){
            boolean result=isHamiltonian(start, nodes[i], hs);
            if(result)return true;
        }
    }
    hs.remove(n);
    return false;
}

问题本身就是NP难的,所以不要指望一般图的快速解决方案。阅读some basic algorithms并确定是否值得花时间为您的应用程序实施。