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