AI: 图搜索和使用曼哈顿启发式的A*算法实现

这是我在佛罗伦萨大学人工智能课程中的项目。我需要解决一个经典游戏:8和15格的滑动拼图。这是我的通用图搜索算法实现:

public abstract class GraphSearch implements SearchAlgorithm {protected Queue<Node> fringe;protected HashSet<Node> closedList;public GraphSearch() {    fringe = createFringe();    closedList = new HashSet<Node>(100);}protected abstract Queue<Node> createFringe();public int getNodeExpanded() {    return closedList.size();}@Overridepublic Solution search(Puzzle puzzle) {    fringe.add(new Node(puzzle.getInitialState(), null, null));    while (!fringe.isEmpty()) {        Node selectedNode = fringe.poll();        if (puzzle.getGoalTest().isGoalState(selectedNode.getState())) {            return new Solution(selectedNode, getNodeExpanded());        }        closedList.add(selectedNode);        LinkedList<Node> expansion = selectedNode.expandNode();        for (Node n : expansion) {            if (!closedList.contains(n) && !fringe.contains(n))                fringe.add(n);        }    }    return new Solution(null, getNodeExpanded());}}

这是我的A*算法代码:

public class AStar extends GraphSearch implements InformedSearch {private Heuristic heuristic;public AStar(Heuristic heuristic) {    setHeuristic(heuristic);}public Heuristic getHeuristic() {    return heuristic;}@Overridepublic void setHeuristic(Heuristic heuristic) {    this.heuristic = heuristic;}@Overrideprotected Queue<Node> createFringe() {    return new PriorityQueue<Node>(1000, new Comparator<Node>() {        @Override        public int compare(Node o1, Node o2) {            o1.setH(heuristic.h(o1));            o2.setH(heuristic.h(o2));            o1.setF(o1.getG() + o1.getH());            o2.setF(o2.getG() + o2.getH());            if (o1.getF() < o2.getF())                return -1;            if (o1.getF() > o2.getF())                return 1;            return 0;        }    });}}

这是我的曼哈顿启发式代码:

    @Overridepublic int h(Node n) {    int distance = 0;    ArrayList<Integer> board = n.getState().getBoard();    int[][] multiBoard = new int[N][N];    for (int i = 0; i < N; i++) {        for (int j = 0; j < N; j++) {            multiBoard[i][j] = board.get(i * N + j);        }    }    for (int i = 0; i < N; i++) {        for (int j = 0; j < N; j++) {            int value = multiBoard[i][j];            if (multiBoard[i][j] != 0) {                int targetX = (value - 1) / N;                int targetY = (value - 1) % N;                distance += Math.abs(i - targetX) + Math.abs(j - targetY);            }        }    }    return distance;}

现在,代码可以工作并找到拼图的解(拼图状态是一个N*N的值数组,目标状态是[1, 2, 3, 4, 5, 6, 7, 8, 9, 0](对于N=3),空白格为0),但是与其他程序(使用相同算法和相同启发式)的结果相比,我的程序扩展了不同数量的节点。我认为通用图搜索中存在问题…有什么想法吗? :D谢谢!!!


回答:

你的启发式计算有误。假设9位于你的棋盘的索引4处。你计算它的rowRight值为3而不是2。这会导致你的算法性能不佳。你的row right计算应该是:

int rowRight = (valueFound - 1) / N;

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注