我有一个要求实现接口方法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;
}
答案 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并确定是否值得花时间为您的应用程序实施。