им жаль, если это длинный вопрос, но я не уверен, работает ли мой java-код A * 8 или нет ... я узнал, что мой код работает просто отлично для простых входы (легко усредненные случаи), но я не знаю, работает ли это в худшем случае ...Время головоломки A * 8 занимает слишком много времени
Я пробовал модифицировать свой код, чтобы использовать расстояния в манхэттене каждого узла для использования в качестве моей эвристической функции, а мой код работает даже в худшем случае, но это занимает слишком много времени ... и когда я использую «количество неуместных плит» в качестве функции эвристики, мой код занимает больше времени, чтобы запускать простые средние случаи по сравнению с использованием расстояний на манхэттанах. он также не дает решения для наихудших сценариев, даже через 15 минут ...
Примечания: в худшем случае, 8 головоломки разрешима не более чем на 31 шагов ...
... Здесь это моя главная функция для моего кода:
List<Node> nodeList = new ArrayList<Node>();
nodeList.add(startNode); //"Node startNode" contains the root node of the tree that will be produced
Node currentNode = null;
while (1 == 1) {
//THIS SECTION FINDS THE LEAF NODE WITH THE LEAST f(n)
currentNode = null;
for (Node pickNode : nodeList) {
if (pickNode.isLeaf == true) {
if (currentNode == null)
currentNode = pickNode;
else if (pickNode.fn < currentNode.fn){
currentNode = pickNode;
}
}
}
/*-----------------------------------------------------------*/
//BREAK THE LOOP WHEN THE SOLUTION IS FOUND
if (Arrays.deepEquals(currentNode.state, goalState))
break;
/*-----------------------------------------------------------*/
else {
int xcheck = currentNode.zeroX;
int ycheck = currentNode.zeroY;
int switcher;
int approve = 1;
/*-----------------------------------------------------------*/
//THE FOLLOWING LINES DETERMINES WHICH CHILDREN CAN BE PRODUCED BY A NODE
if ((ycheck - 1) >= 0) {
int subState[][] = new int [3][];
subState[0] = currentNode.state[0].clone();
subState[1] = currentNode.state[1].clone();
subState[2] = currentNode.state[2].clone();
switcher = subState[ycheck-1][xcheck];
subState[ycheck-1][xcheck] = 0;
subState[ycheck][xcheck] = switcher;
Node checkerNode = new Node();
checkerNode = currentNode;
while (checkerNode != null) {
if (Arrays.deepEquals(subState, checkerNode.state)) {
approve = 0;
break;
}
checkerNode = checkerNode.parentNode;
}
if (approve != 0) {
Node childNode = new Node();
childNode.state = subState;
childNode.totalPath = currentNode.totalPath + "*" + "up";
childNode.gn = currentNode.gn + 1;
childNode.hn = computeHn(childNode.state, goalState);
childNode.fn = childNode.gn + childNode.hn;
childNode.isLeaf = true;
childNode.parentNode = currentNode;
childNode.zeroX = xcheck;
childNode.zeroY = ycheck-1;
nodeList.add(childNode);
}
}
approve = 1;
/*-----------------------------------------------------------*/
if ((ycheck + 1) <= 2) {
//same logic with: if (ycheck-1 >= 0)
}
approve = 1;
/*-----------------------------------------------------------*/
if ((xcheck + 1) <= 2) {
//same logic with: if (ycheck-1 >= 0)
}
approve = 1;
/*-----------------------------------------------------------*/
if ((xcheck - 1) >= 0) {
//same logic with: if (ycheck-1 >= 0)
}
approve = 1;
}
currentNode.isLeaf = false;
}
Вот функция, которая вычисляет для моей эвристики (количество неуместных плиток вместо Манхэттенского расстояния):
public static int computeHn (int checkStateH[][], int goalStateH[][]) {
int total = 0;
int rowC = 0;
int columnC = 0;
rowC = 0;
while (rowC < 3) {
columnC = 0;
while (columnC < 3) {
if (goalStateH[rowC][columnC] != checkStateH[rowC][columnC]) {
total++;
}
columnC++;
}
rowC++;
}
return total;
}
и вот мой Класс Узел:
public class Node {
int state[][]; //contains the matrix configuration of the node
String totalPath; //contains the path on how to get to this node from the root node
int gn; //contains the number of moves made to get to this node from the root node
int hn; //contains the heuristic (number of misplaced tiles per node)
int fn; // fn = gn + hn
boolean isLeaf; //states whether a node is a leaf or not. used so that I can know whether a node could still be expanded or not
Node parentNode; //points to the node's parent node
int zeroX; //the x position of the zero tile
int zeroY; //the y position of the zero tile
}
Это данная матрица, или матрица "начальное состояние" (на худшем случае, это может дать ответ на 31 ходов на минимум):
... и он должен достичь этого конечного состояния:
... опять же, когда я использую "Манхеттен расстояние", как моя функция эвристического, мой код работает, но это занимает 30 secs, чтобы дать ответ для такого ввода ... но когда я использую «количество неуместных плит» в качестве функции эвристики, оно не дает решения даже через 15 минут, но дает ответ, когда я использую эту матрицу:
- 3 0 4 // эта матрица достижима из ранее упомянутого состояния матрицы запуска
... спасибо за тех, кто будет помогать! ... я прошу прощения, если его но я думал, что должен опубликовать свой код вместо того, чтобы просто указывать логику моего кода, так как я мог ошибаться в реализации моей логики ...
о, checkerNode только проверяет, является ли childNode, что будет выпускаться будет иметь состояние, которое то же самое с его родителями/предками. если это так, то childNode больше не будет выпущен ... – JennyMelody
извините, это может быть глупый вопрос, но что вы подразумеваете под «словарем состояний»? это какой-то список? или я могу использовать мой nodeList, где я пройду узел nodeList и проведу, будет ли дочернийNode, который будет создан, будет иметь такое же состояние с другим существующим узлом (будь то лист или нет), и если этот узел с таким же состоянием имеет меньше f (n), чем childNode, который будет создан, прервать производство childNode ...? :( – JennyMelody
Это совсем не глупый вопрос. Я отредактировал свой ответ, чтобы лучше объяснить словари и как его использовать здесь. Это похоже на переезд nodeList, но гораздо быстрее. Я рад предоставить больше разъяснений, если он по-прежнему не имеет смысла :). – seaotternerd