使用曼哈顿启发式算法的IDA *算法的正确实现是什么?

时间:2014-05-23 11:39:24

标签: ios objective-c puzzle heuristics

我正在尝试实现IDA *算法来解决目标C中的15个难题,我已经很好地实现了算法但没有得到确切的结果。这是我的代码 -

- (TreeNode *)IDAStarSolution:(TreeNode *)startState {
int limit = 5;//2*[startState fx];

appDelegate.CN=[NSNumber numberWithInt:limit];

TreeNode *result=nil;

while (result==nil) {
    [appDelegate.closedList addObject:startState];
    newLimit = 99999;
    result = [self depthLimitSearch:startState costLimit:limit];
    limit = newLimit;
    appDelegate.CN=[NSNumber numberWithInt:newLimit];
    [appDelegate.closedList removeAllObjects];
}
return result;
}

- (TreeNode*)depthLimitSearch:(TreeNode *)current costLimit:(int)currentCostBound {
NSArray *neighbors =[current expandNodeToChilds];
for (TreeNode *s in neighbors) {
    if ([s.puzzleBox isFinalStateBox]) {
        appDelegate.result=s.moveString;
        return s;
    }

    if (![self closedSetContains:s]) {

        int currentCost = [s.cost intValue] + [s.puzzleBox.manhattanDistance intValue];
        if (currentCost <= currentCostBound) {
            [appDelegate.closedList addObject:s];
            [s.puzzleBox displayPuzzleBox];

            TreeNode *solution = [self depthLimitSearch:s costLimit:currentCostBound];
            if (solution!=nil&& (bestSolution ==nil|| [solution.cost intValue] < [bestSolution.cost intValue])) {
                bestSolution = solution;
                //return solution;
            }
        }else {
            if (currentCost < newLimit) {
                NSLog(@"new limit %d", currentCost);
                newLimit = currentCost;
            }
        }
    }
}
return bestSolution;
}


-(BOOL)closedSetContains:(TreeNode *)node{
for (TreeNode *tNode in appDelegate.closedList) {
    if (tNode==node) {
        return YES;
    }
}
return NO;
}

depthLimitedSearch始终返回null,然后一次又一次地展开同一节点。 所以我做错了请建议。

实现类似于下面给出的java代码: Iterative Deepening A Star (IDA*) to solve n-puzzle (sliding puzzle) in Java

当我现在返回bestSolution时,如果我将限制设置为超过最佳成本,那么它将返回它找到的第一个解决方案,这不是最佳解决方案。现在该怎么办?

1 个答案:

答案 0 :(得分:1)

我认为您的突变/枚举问题是由closedSetContains方法的结构引起的。您正在枚举appDelegate.closedList但是从枚举的中间返回。我怀疑当你修改appDelegate.closedList时它会导致错误,因为看起来枚举仍然是活动的。您应该能够通过在调试器中使用数组appDelegate.closedList检查异常中的数组引用来确认这一点。

closedSetContains更改为此 -

-(BOOL)closedSetContains:(TreeNode *)node{
  BOOL ret=NO;
  for (TreeNode *tNode in appDelegate.closedList) {
    if (tNode==node) {
      ret=YES;
      break;
    }
  }

  return ret;
}

可能有所帮助。但如果appDelegate.closedList是NSMutableArray,您可以用[appDelegate.closedList containsObject:node]替换整个方法