Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java堆空间不足-15个难题_Java_Algorithm_Performance_Heap_Puzzle - Fatal编程技术网

java堆空间不足-15个难题

java堆空间不足-15个难题,java,algorithm,performance,heap,puzzle,Java,Algorithm,Performance,Heap,Puzzle,一整天, 我试着解决八道难题 由joel Neely编写,并对其进行了修改,以便用于求解更高的网格[将网格的字符串表示形式更改为二维整数表示形式,并进行了修改 相应地,逻辑也是如此。但是,修改后的代码可以解决3x3网格,但很快就会耗尽4x4网格的堆空间。我想这是由于所使用的算法所造成的限制,我认为这是有一定局限性的 分支和边界的变化,而不是java的变化。如果我的假设是正确的,有人能提出其他解决这个问题的好算法吗?。如果没有,请提示可以做些什么来制作这个程序 为高阶网格工作 import jav

一整天, 我试着解决八道难题 由joel Neely编写,并对其进行了修改,以便用于求解更高的网格[将网格的字符串表示形式更改为二维整数表示形式,并进行了修改 相应地,逻辑也是如此。但是,修改后的代码可以解决3x3网格,但很快就会耗尽4x4网格的堆空间。我想这是由于所使用的算法所造成的限制,我认为这是有一定局限性的 分支和边界的变化,而不是java的变化。如果我的假设是正确的,有人能提出其他解决这个问题的好算法吗?。如果没有,请提示可以做些什么来制作这个程序 为高阶网格工作

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;

class EightPuzzle {

    //Queue<Integer[][]> agenda = new LinkedList<Integer[][]>();    // Use of Queue Implemented using LinkedList for Storing All the Nodes in BFS.
    //Map<Integer[][],Integer> stateDepth = new HashMap<Integer[][], Integer>(); // HashMap is used to ignore repeated nodes
    //Map<Integer[][],Integer[][]> stateHistory = new HashMap<Integer[][],Integer[][]>(); // relates each position to its predecessor
    Map<String,String> stateHistory = new HashMap<String,String>(); // relates each position to its predecessor
    Map<String,Integer> stateDepth = new HashMap<String,Integer>();
    Queue<Integer[][]> agenda=new LinkedList<Integer[][]>();
    final int GRIDSIZE=4;
    int row=0,col=0;
    public static void main(String args[]){

       // Integer[][] str="087465132";                                 // Input the Board State as a Integer[][] with 0 as the Blank Space
        Integer init[][]={{1,3,12,4},{2,9,10,7},{0,14,8,15},{5,6,13,11}};
        //Integer init[][]={{0,8,7},{4,6,5},{1,3,2}};
        EightPuzzle e = new EightPuzzle();              // New Instance of the EightPuzzle

        e.add(init,null);                                                   // Add the Initial State

        while(!e.agenda.isEmpty()){
            Integer[][] currentState = e.agenda.remove();
            e.up(currentState);                                       // Move the blank space up and add new state to queue
            e.down(currentState);                                     // Move the blank space down
            e.left(currentState);                                     // Move left
            e.right(currentState);                          // Move right and remove the current node from Queue
        }

        System.out.println("Solution doesn't exist");
    }

    //Add method to add the new Integer[][] to the Map and Queue
    void add(Integer newState[][], Integer oldState[][]){
        if(!stateDepth.containsKey(convertToString(newState))){
            int newValue = oldState == null ? 0 : stateDepth.get(convertToString(oldState)) + 1;
            stateDepth.put(convertToString(newState), newValue);
            agenda.add(newState);
            stateHistory.put(convertToString(newState), convertToString(oldState));
        }
    }

    /* Each of the Methods below Takes the Current State of Board as Integer[][]. Then the operation to move the blank space is done if possible.
      After that the new Integer[][] is added to the map and queue.If it is the Goal State then the Program Terminates.
     */
    void up(Integer[][] currentState){
        Integer[][] nextState=new Integer[GRIDSIZE][GRIDSIZE];
        getIndicesOfZero(currentState, nextState);
        if(row!=0){
            nextState[row-1][col]=currentState[row][col];
            nextState[row][col]=currentState[row-1][col];
            checkCompletion(currentState, nextState);
        }
    }

    /**
     * @param currentState
     */
    /**
     * @param currentState
     */
    void down(Integer[][] currentState){
        Integer[][] nextState=new Integer[GRIDSIZE][GRIDSIZE];
        getIndicesOfZero(currentState, nextState);
        if(row!=GRIDSIZE-1){
            nextState[row+1][col]=currentState[row][col];
            nextState[row][col]=currentState[row+1][col];  
            checkCompletion(currentState, nextState);
        }
    }
    void left(Integer[][] currentState){
        Integer[][] nextState=new Integer[GRIDSIZE][GRIDSIZE];
        getIndicesOfZero(currentState, nextState);
        if(col!=0){
            nextState[row][col-1]=currentState[row][col];
            nextState[row][col]=currentState[row][col-1];
            checkCompletion(currentState, nextState);
        }
    }
    void right(Integer[][] currentState){
        Integer[][] nextState=new Integer[GRIDSIZE][GRIDSIZE];
        getIndicesOfZero(currentState, nextState);
        if(col!=GRIDSIZE-1){
            nextState[row][col+1]=currentState[row][col];
            nextState[row][col]=currentState[row][col+1];
            checkCompletion(currentState, nextState);
        }
    }

    private void checkCompletion(Integer[][] oldState, Integer[][] newState) {
        add(newState, oldState);
        Integer[][] completeState={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,0}};
        //Integer[][] completeState={{1,2,3},{4,5,6},{7,8,0}};
        boolean equality=true;
        outer:for(int i=0;i<GRIDSIZE;i++){
            for(int j=0;j<GRIDSIZE;j++){
                if(newState[i][j]!=completeState[i][j]){
                    equality=false;
                    break outer;
                }
            }
        }

        if(equality){
            System.out.println("Solution Exists at Level "+stateDepth.get(convertToString(newState))+" of the tree");
            String traceState = convertToString(newState);
            while (traceState != null) {   
                System.out.println(traceState + " at " + stateDepth.get(traceState));
                traceState = stateHistory.get(traceState);
            }
            System.exit(0);

        }
    }
    String convertToString(Integer[][] a){
        String str="";
        if(a!=null){
            for(int i=0;i<GRIDSIZE;i++){
                for(int j=0;j<GRIDSIZE;j++){
                    str+=a[i][j];
                }
            }
        }
        else{
            str=null;
        }
        return str;
    }
    void getIndicesOfZero(Integer[][] currentState,Integer[][] nextState){
        for(int i=0;i<GRIDSIZE;i++){
            for(int j=0;j<GRIDSIZE;j++){
                nextState[i][j]=currentState[i][j];
            }
        }
        outer:for(int i=0;i<GRIDSIZE;i++){
            for(int j=0;j<GRIDSIZE;j++){
                if(currentState[i][j]==0){
                    row=i;
                    col=j;
                    break outer;
                }
            }
        }

    }
}
import java.util.HashMap;
导入java.util.LinkedList;
导入java.util.Map;
导入java.util.Queue;
第八类{
//Queue agenda=new LinkedList();//使用LinkedList实现的队列存储BFS中的所有节点。
//Map stateDepth=new HashMap();//HashMap用于忽略重复的节点
//Map stateHistory=new HashMap();//将每个位置与其前身关联
Map stateHistory=new HashMap();//将每个位置与其前身关联
Map stateDepth=newhashmap();
队列议程=新建LinkedList();
最终int GRIDSIZE=4;
int行=0,列=0;
公共静态void main(字符串参数[]){
//整数[]]STR=“087465132”;/ /将板状态输入为整数[]],以0作为空白空间
整数init[][]={{1,3,12,4},{2,9,10,7},{0,14,8,15},{5,6,13,11};
//整数init[][]={{0,8,7},{4,6,5},{1,3,2};
EightPuzzle=新的EightPuzzle();//EightPuzzle的新实例
e、 add(init,null);//添加初始状态
而(!e.agenda.isEmpty()){
整数[][]当前状态=e.agenda.remove();
E. UP(CurrnType);/ /移动空白空间并向队列添加新的状态
E.向下(当前状态);/ /向下移动空白区域
e、 左(当前状态);//向左移动
e、 右(currentState);//向右移动并从队列中删除当前节点
}
System.out.println(“解决方案不存在”);
}
//Add方法将新整数[]添加到映射和队列中
void add(整数newState[]],整数oldState[]]{
if(!stateDepth.containsKey(convertToString(newState))){
int newValue=oldState==null?0:stateDepth.get(convertToString(oldState))+1;
stateDepth.put(convertToString(newState),newValue);
议程.增补(新闻状态);
stateHistory.put(convertToString(newState)、convertToString(oldState));
}
}
/*下面的每一个方法将当前的板状态作为整型[]],然后尽可能地移动空白空间。
之后,新的整数[]被添加到映射和队列中。如果它是目标状态,则程序终止。
*/
向上作废(整数[][]当前状态){
整数[][]nextState=新整数[GRIDSIZE][GRIDSIZE];
GetIndicateSofzero(当前状态,下一个状态);
如果(行!=0){
nextState[row-1][col]=当前状态[row][col];
nextState[row][col]=当前状态[row-1][col];
检查完成(当前状态、下一状态);
}
}
/**
*@param currentState
*/
/**
*@param currentState
*/
向下作废(整数[][]当前状态){
整数[][]nextState=新整数[GRIDSIZE][GRIDSIZE];
GetIndicateSofzero(当前状态,下一个状态);
如果(行!=GRIDSIZE-1){
nextState[行+1][col]=当前状态[行][col];
下一个状态[行][col]=当前状态[行+1][col];
检查完成(当前状态、下一状态);
}
}
左空(整数[][]当前状态){
整数[][]nextState=新整数[GRIDSIZE][GRIDSIZE];
GetIndicateSofzero(当前状态,下一个状态);
如果(列!=0){
nextState[row][col-1]=当前状态[row][col];
nextState[row][col]=当前状态[row][col-1];
检查完成(当前状态、下一状态);
}
}
无效权限(整数[][]当前状态){
整数[][]nextState=新整数[GRIDSIZE][GRIDSIZE];
GetIndicateSofzero(当前状态,下一个状态);
如果(列!=GRIDSIZE-1){
下一状态[行][col+1]=当前状态[行][col];
nextState[row][col]=当前状态[row][col+1];
检查完成(当前状态、下一状态);
}
}
私有无效检查完成(整数[][]旧状态,整数[][]新状态){
添加(newState、oldState);
整数[][]completeState={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,0};
//整数[][]completeState={{1,2,3},{4,5,6},{7,8,0};
布尔等式=真;

外部:对于(int i=0;i您的算法缺乏启发式。换句话说,它在没有指导的情况下探索搜索空间。对于15个谜题,该空间相当大,接近3**(解的深度)

如果您根据每个磁贴到其目的地的曼哈顿距离之和来排列队列,这可能足以使其可解。在每个步骤中,以最小的“错误”展开议程上的项目

另外,你确定你所选择的开始状态是可解的吗?如果你随机排列瓷砖,你只有50-50的机会

最后,您可以从
Integer
切换到
byte
,以节省内存。这在多大程度上取决于java实现,但由于Integer是一个类,byte是一个基本类型,因此它可能很重要


更新了

您的算法缺少启发式。换句话说,它在没有指导的情况下探索搜索空间。对于15个谜题