1
This is my project在佛羅倫薩大學的AI課程。我必須解決一個經典的遊戲:滑動拼圖8和15單元格。 這是我實現一般圖搜索算法:AI:在曼哈頓啓發式圖搜索和A *實現
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();
}
@Override
public 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;
}
@Override
public void setHeuristic(Heuristic heuristic) {
this.heuristic = heuristic;
}
@Override
protected 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;
}
});
}
}
這是我的曼哈頓啓發式代碼:
@Override
public 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)與空白cell = 0),但將結果與其他程序進行比較ams(相同的算法和相同的啓發式)我的程序擴展了不同數量的節點。我認爲在一般的圖形搜索中存在一個問題......任何想法? :D 謝謝!
你是對的!在曼哈頓啓發式有一個錯誤...但有了你的建議,有時它仍然是壞 – Mulder90
好吧現在曼哈頓啓發式是正確的https://github.com/Mulder90/Sliding-Puzzle/blob/master/Sliding%20Puzzle/src/com /lorenzocinque/puzzle/core/heuristic/ManhattanHeuristic.java – Mulder90
是的,它似乎是正確的。你的結果現在是否最佳? – mkirci