Java 无法确定我的IDA*实现是否存在缺陷或效率低下
我实现了迭代深化a-star搜索(用于8字谜问题,但可以接受其他问题),并在输入上运行它。它运行了两个小时都没有成功。对于接近目标节点的简单输入,它可以正常工作。其他人已经为这一投入工作。我不确定我的实现是效率低下还是陷入无限循环 java$idaJava 无法确定我的IDA*实现是否存在缺陷或效率低下,java,search,artificial-intelligence,sliding-tile-puzzle,Java,Search,Artificial Intelligence,Sliding Tile Puzzle,我实现了迭代深化a-star搜索(用于8字谜问题,但可以接受其他问题),并在输入上运行它。它运行了两个小时都没有成功。对于接近目标节点的简单输入,它可以正常工作。其他人已经为这一投入工作。我不确定我的实现是效率低下还是陷入无限循环 java$ida /** Accepts start node root and string identifying whihc heuristic to use * h1 is number of misplaced tiles and h2
/** Accepts start node root and string identifying whihc heuristic to use
* h1 is number of misplaced tiles and h2 is Manhattan distance
*/
private Node ida(Node root, final String h) {
PriorityQueue<DNode> frontier = new PriorityQueue<DNode>(10, new Comparator<DNode>(){
@Override
public int compare(DNode n1, DNode n2) {
if(h == "h1") {
if(n1.depth + h1(n1.node) > n2.depth + h1(n2.node)) return 1;
if(n1.depth + h1(n1.node) < n2.depth + h1(n2.node)) return -1;
return 0;
}
if(h == "h2") {
if(n1.depth + h2(n1.node) > n2.depth + h2(n2.node)) return 1;
if(n1.depth + h2(n1.node) < n2.depth + h2(n2.node)) return -1;
return 0;
}
return 0;
}});
ArrayList<Node> explored = new ArrayList<Node>();
Node soln = null;
DNode start = new DNode(root, 1);
frontier.add(start);
int d = 0;
int flimit = (h == "h1" ? h1(start.node) : h2(start.node));
int min = flimit;
while(true) {
DNode dn = frontier.poll();
if(dn == null) {
frontier.add(start);
d = 0;
flimit = min;
continue;
}
d = dn.depth;
Node n = dn.node;
//n.print();
if(goalCheck(n)){
return n;
}
for(int i = 0;i < ops.length;i++) {
String op = ops[i];
if(n.applicable(op)) {
soln = n.applyOp(op);
int h_cost;
if(h == "h1") h_cost = h1(soln);
else h_cost = h2(soln);
if(!checkDup(explored,soln) && d + 1 + h_cost < flimit) {
frontier.add(new DNode(soln, d + 1));
DNode least = frontier.peek();
min = least.depth + (h == "h1" ? h1(least.node) : h2(least.node));
}
}
}
explored.add(n);
max_list_size = Math.max(max_list_size, frontier.size() + explored.size());
}
}
目标国:
1 3 4
8 6 2
7 - 5
(曾为1438670752工作)
我没有包括Node.java,因为我非常确定它在运行其他搜索算法(如best first、dfs)后可以工作。很难提供SCCE,所以我只是想寻求帮助,找出ida实现中任何明显的错误
编辑:已解决问题,但仍试图在无法达到目标时确定终止条件。IDA*没有保存已探索节点的列表,因此我如何知道我是否已覆盖了整个解决方案空间?您的
checkDup
功能效率非常低。我建议使用哈希集
:
您的函数在集合的大小上具有线性成本,而HashSet的contains
方法具有恒定成本
java中的字符串与equals
进行比较:
可能还有其他问题,但这是我在快速检查您的代码后发现的两个最明显的问题。我计算新flimit的方法有一个错误。在其他情况下,它并没有引起问题,因为后继对象的限制不会导致它无限循环。此外,条件f(当前节点)n2.depth+h1(n2.node))应返回1;
if(n1.depth+h1(n1.node)n2.depth+h2(n2.node))返回1;
if(n1.depth+h2(n1.node) 如果(d+1+h_按照建议使用哈希集并进行尝试会产生成本。我不是在比较字符串,而是比较整数,因此这不是一个bug。强制性的8字谜注释:请注意,只有一半的开始状态是可解的,在考虑调试代码之前,请确保您没有尝试解决其中一个。是的,目标节点是rea夏布利斯:这是一个十字柱吗。
1 2 3
8 - 4
7 6 5
1 3 4
8 6 2
7 - 5
private Node ida(Node root, final String h) {
PriorityQueue<DNode> frontier = new PriorityQueue<DNode>(10, new Comparator<DNode>(){
@Override
public int compare(DNode n1, DNode n2) {
if(h == "h1") {
if(n1.depth + h1(n1.node) > n2.depth + h1(n2.node)) return 1;
if(n1.depth + h1(n1.node) < n2.depth + h1(n2.node)) return -1;
return 0;
}
if(h == "h2") {
if(n1.depth + h2(n1.node) > n2.depth + h2(n2.node)) return 1;
if(n1.depth + h2(n1.node) < n2.depth + h2(n2.node)) return -1;
return 0;
}
return 0;
}});
ArrayList<Node> explored = new ArrayList<Node>();
Node soln = null;
DNode start = new DNode(root, 1);
frontier.add(start);
int d = 0;
int flimit = (h == "h1" ? h1(start.node) : h2(start.node));
int min = flimit;
while(true) {
DNode dn = frontier.poll();
if(dn == null) {
explored.clear();
frontier.add(start);
d = 0;
flimit = min;
continue;
}
d = dn.depth;
Node n = dn.node;
//n.print();
if(goalCheck(n)){
return n;
}
min = Integer.MAX_VALUE;
for(int i = 0;i < ops.length;i++) {
String op = ops[i];
if(n.applicable(op)) {
soln = n.applyOp(op);
int h_cost;
if(h == "h1") h_cost = h1(soln);
else h_cost = h2(soln);
if(!checkDup(explored,soln)) {
if(d + 1 + h_cost <= flimit) {
frontier.add(new DNode(soln, d + 1));
}
else {
if(d + 1 + h_cost < min)min = d + 1 + h_cost;
}
}
}
}
explored.add(n);
max_list_size = Math.max(max_list_size, frontier.size() + explored.size());
}
}