对于我的大学项目,我正在创建一个求解器,它可以找到并返回最快的方法来求解8和15难题。这是一个滑动难题,其中您有一个带有数字的图块网格,而一个图块为空。主要目标是以这种方式重新排列图块,以使数字顺序正确。
它可以解决任何8个难题,但是当我经过长时间的计算之后增加网格的大小(15个难题)时,程序停止执行并返回以下错误:
Exception in thread "JavaFX Application Thread" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.util.HashMap.resize(HashMap.java:704)
at java.util.HashMap.putVal(HashMap.java:629)
at java.util.HashMap.put(HashMap.java:612)
at Game.Board.createDictionary(Board.java:137)
at Game.Board.<init>(Board.java:16)
at Game.Board.GetNeighbors(Board.java:51)
at Game.Board.neighbors(Board.java:42)
at Solution.Solver.A_Star(Solver.java:61)
at Solution.Solver.<init>(Solver.java:33)
at Game.guiInterface.lambda$SolveAction$4(guiInterface.java:166)
at Game.guiInterface$$Lambda$80/1945550891.handle(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8411)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
这是我的求解器类:
package Solution;
import Game.Board;
import Game.State;
import java.util.*;
public class Solver {
public Stack<int[][]> states;
private int[][] start;
//3x3 GOAL
// private int[][] goal = {
// {1, 2, 3},
// {4, 5, 6},
// {7, 8, 0},
// };
// // 4x4 GOAL
private int[][] goal = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 0}
};
private Board startBoard;
private Board endBoard = new Board(goal);
public Solver(int[][] start) {
this.start = start;
startBoard = new Board(this.start);
A_Star(startBoard, endBoard);
}
public String toString() {
return " ";
}
public void A_Star(Board start, Board goal) {
PriorityQueue<State> openSet = new PriorityQueue<>();
State startStage = new State(start, null, 0);
State goalStage = new State(goal, null, 0);
openSet.add(startStage);
Map<int[][], State> score = new HashMap<>();
score.put(start.boardNumbers, startStage);
State previous;
while (!openSet.isEmpty()) {
State current = openSet.poll();
previous = current.getParent();
if (current.equals(goalStage)) {
System.out.println(score.size());
Print(current);
break;
}
List<Board> neighbors = current.getBoardPosition().neighbors(null);
for (Board item : neighbors) {
State neighbor = new State(item, current, current.getMovesCount() + 1);
if (previous != null) {
if (!previous.equals(neighbor))
openSet.add(neighbor);
}
else
openSet.add(neighbor);
if (score.containsKey(neighbor.getBoardPosition().boardNumbers)) {
UpdateScore(score, neighbor);
openSet.remove(neighbor);
openSet.add(neighbor);
}
else {
score.put(neighbor.getBoardPosition().boardNumbers, neighbor);
}
}
}
}
private void Print(State current) {
State letsGo = current;
states = new Stack<>();
while (letsGo != null) {
states.add(letsGo.getBoardPosition().boardNumbers);
letsGo = letsGo.getParent();
}
}
private void UpdateScore(Map<int[][], State> score, State neighbor) {
int[][] neighborNumbers = neighbor.getBoardPosition().boardNumbers;
int neighborScore = neighbor.getPriorityNumber();
if (score.get(neighborNumbers).getPriorityNumber() > neighborScore) {
score.put(neighborNumbers, neighbor);
}
}
}
如果我正确理解主要问题在于搜索算法。 HashMap存储了太多对象,最终计算机内存不足。
任何建议如何解决?也许我在算法中做了不必要的事情,这会导致内存泄漏?