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

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

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