解决15个难题时超出了GC开销限制

时间:2018-12-10 16:59:53

标签: java 8-puzzle

对于我的大学项目,我正在创建一个求解器,它可以找到并返回最快的方法来求解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存储了太多对象,最终计算机内存不足。

任何建议如何解决?也许我在算法中做了不必要的事情,这会导致内存泄漏?

0 个答案:

没有答案