线程 “main” 中出现 java.lang.StackOverflowError 问题

我需要你的帮助。我不知道为什么我的代码在维度为10且脏槽位为11时会失败,请帮帮我。

package Strategies;import java.util.LinkedList;import java.util.Queue;import Cleaning.State;public class BFS {private int dirty;private Queue<State> fifo = new LinkedList<State>();private String path = "";private int num_of_expanded_states;private boolean failure = false;public BFS(State state, int dirty) {    // TODO Auto-generated constructor stub    this.dirty = dirty;    this.num_of_expanded_states = 0;    this.fifo.add(state);}public void startCleaning() {    // TODO Auto-generated method stub    successorFunction(fifo.element());    if(failure){        System.out.println("在最大脏槽位数的限制下没有解决方案");        return;    }}public void successorFunction(State state){    int x,y,i;    State temp = new State(state);//      state.printRoom();    if(goalTest(state)){        printPath(state);        return;    }    x = state.x;    y = state.y;    // 检查有效移动    if(x+3 <= state.room.length-1){        if(y+1 <= state.room.length-1){            if(state.room[x+1][y]==1 && state.room[x+2][y]==1 && state.room[x+3][y]==1 && state.room[x+3][y+1]==1){                for(i=1;i<=3;i++){                    temp.room[x+i][y]=0;                }                temp.room[x+i-1][y+1]=0;                temp.x = x+i-1;                temp.y = y+1;                temp.father = new State(state);                temp.action = "3";                fifo.add(temp);            }        }        temp = new State(state);        if(y-1 >= 0){            if(state.room[x+1][y]==1 && state.room[x+2][y]==1 && state.room[x+3][y]==1 && state.room[x+3][y-1]==1){                for(i=1;i<=3;i++){                    temp.room[x+i][y]=0;                }                temp.room[x+i-1][y-1]=0;                temp.x = x+i-1;                temp.y = y-1;                temp.father = new State(state);                temp.action = "1";                fifo.add(temp);            }        }    }    temp = new State(state);    if(x-3 >= 0){        if(y+1 <= state.room.length-1){            if(state.room[x-1][y]==1 && state.room[x-2][y]==1 && state.room[x-3][y]==1 && state.room[x-3][y+1]==1){                for(i=1;i<=3;i++){                    temp.room[x-i][y]=0;                }                temp.room[x-i+1][y+1]=0;                temp.x = x-i+1;                temp.y = y+1;                temp.father = new State(state);                temp.action = "5";                fifo.add(temp);            }        }        temp = new State(state);        if(y-1 >= 0){            if(state.room[x-1][y]==1 && state.room[x-2][y]==1 && state.room[x-3][y]==1 && state.room[x-3][y-1]==1){                for(i=1;i<=3;i++){                    temp.room[x-i][y]=0;                }                temp.room[x-i+1][y-1]=0;                temp.x = x-i+1;                temp.y = y-1;                temp.father = new State(state);                temp.action = "7";                fifo.add(temp);            }        }    }    temp = new State(state);    if(y+3 <= state.room.length-1){        if(x+1 <= state.room.length-1){            if(state.room[x][y+1]==1 && state.room[x][y+2]==1 && state.room[x][y+3]==1 && state.room[x+1][y+3]==1){                for(i=1;i<=3;i++){                    temp.room[x][y+i]=0;                }                temp.room[x+1][y+i-1]=0;                temp.x = x+1;                temp.y = y+i-1;                temp.father = new State(state);                temp.action = "2";                fifo.add(temp);            }        }        temp = new State(state);        if(x-1 >= 0){            if(state.room[x][y+1]==1 && state.room[x][y+2]==1 && state.room[x][y+3]==1 && state.room[x-1][y+3]==1){                for(i=1;i<=3;i++){                    temp.room[x][y+i-1]=0;                }                temp.room[x-1][y+i-1]=0;                temp.x = x-1;                temp.y = y+i-1;                temp.father = new State(state);                temp.action = "4";                fifo.add(temp);            }        }    }    temp = new State(state);    if(y-3 >= 0){        if(x+1 <= state.room.length-1){            if(state.room[x][y-1]==1 && state.room[x][y-2]==1 && state.room[x][y-3]==1 && state.room[x+1][y-3]==1){                for(i=1;i<=3;i++){                    temp.room[x][y-i]=0;                }                temp.room[x+1][y-i+1]=0;                temp.x = x+1;                temp.y = y-i+1;                temp.father = new State(state);                temp.action = "0";                fifo.add(temp);            }        }        temp = new State(state);        if(x-1 >= 0){            if(state.room[x][y-1]==1 && state.room[x][y-2]==1 && state.room[x][y-3]==1 && state.room[x-1][y-3]==1){                for(i=1;i<=3;i++){                    temp.room[x][y-i]=0;                }                temp.room[x-1][y-i+1]=0;                temp.x = x-1;                temp.y = y-i+1;                temp.father = new State(state);                temp.action = "6";                fifo.add(temp);            }        }    }    num_of_expanded_states = num_of_expanded_states+1;    // return    fifo.remove();    if(fifo.isEmpty()){        failure = true;        return;    }    else{        successorFunction(fifo.element());    }}public boolean goalTest(State state){    int counter = 0;    for (int i=0;i<state.room.length;i++){        for (int j=0;j<state.room.length;j++){            if(state.room[i][j] == 1){                counter++;            }        }    }    if(counter <= dirty){        return true;    }    else{               return false;    }}public int pathCost(String path){    if(path.equals(null)){        return 0;    }    path.split("(?!^)");    return path.length();}public void printPath(State goal_state){    System.out.println(calculatePath(goal_state));    System.out.println("扩展节点的数量为: "+num_of_expanded_states);}public String calculatePath(State state){    if(state.father==null){        return path;    }    return calculatePath(state.father).concat(state.action);}}

这是 State 类的代码:

package Cleaning;public class State {public  long[][] room;public State father;public String action;public int x;public int y;public State(State another){    this.room = new long[another.room.length][another.room.length];    this.father = another.father;    this.x = another.x;    this.y = another.y;    this.action = another.action;    for(int i=0; i<this.room.length; i++)        for(int j=0; j<this.room.length; j++)            this.room[i][j] = another.room[i][j];}public State() {    // TODO Auto-generated constructor stub}public void initializeState(int dimention){         int i,j;    this.room = new long[dimention][dimention];    this.action = "";    this.father = new State();    father = null;    this.x = dimention - 1;    this.y = 0;    for(i=0;i<dimention;i++){        for(j=0;j<dimention;j++){            if(i == (dimention-1) && j==0){                room[i][j] = 0;            }            else{                room[i][j] = 1;            }        }    }}public void printRoom(){    for(int i=0;i<room.length;i++){        for(int j=0;j<room.length;j++){            System.out.print(room[i][j]+" ");        }        System.out.println();    }}}

我尝试了一切方法但无法解决这个异常,请帮帮我。谢谢你的帮助

日志如下:

Exception in thread "main" java.lang.StackOverflowError at java.util.LinkedList.removeFirst(Unknown Source)at java.util.LinkedList.remove(Unknown Source) at Strategies.BFS.successorFunction(BFS.java:195)at Strategies.BFS.successorFunction(BFS.java:201)at Strategies.BFS.successorFunction(BFS.java:201)at Strategies.BFS.successorFunction(BFS.java:201)at Strategies.BFS.successorFunction(BFS.java:201)at Strategies.BFS.successorFunction(BFS.java:201)at Strategies.BFS.successorFunction(BFS.java:201) 以上类似的行有很多,所以我无法全部列出

回答:

你可以通过将 successFunction 从递归改为迭代来解决你的堆栈溢出问题,例如:

private void successsFunction(State another) {

  ...  else {     successFunction(fifo.element());  }

}

改为

private void successFunction() {  while(!fifo.isEmpty()) {    another = fifo.element();    ...  }}

这样可以解决堆栈溢出的问题,但可能会导致程序运行变慢或内存不足。

我认为你的真正问题是由于你标记房间已访问的方式以及每次创建新状态时复制房间状态的方式,导致你多次重复访问相同的房间。

从你的代码来看

public State(State another){    this.room = new long[another.room.length][another.room.length];    ....    for(int i=0; i<this.room.length; i++)        for(int j=0; j<this.room.length; j++)            this.room[i][j] = another.room[i][j];}...private successFunction() {  ...  for(i=1;i<=3;i++){     temp.room[x][y+i]=0;  }

这意味着你只标记了这些房间在这个房间及其子房间中已访问。如果我们有一个简单的房子,房间1连接到房间10和11,房间10连接到房间11、100和101,房间11连接到房间10、110和111。

  • 你会访问房间1,标记为已访问,添加房间10和11 [递归] 队列=[10,11]
  • 访问房间10,标记为已访问,添加房间11、100和101 [递归] 队列=[11,11,100,101]
  • 访问房间11,标记为已访问,添加房间110和111 [递归] 队列=[11,100,101,110,111]
  • 再次访问房间11,标记为已访问,添加房间110和111 [递归] 队列=[11,100,101,110,111,110,111]

如果你在每次 successFunction 开始时打印出你所在的房间,以及 fifo 队列中的房间,你会明白我的意思。

我建议的解决方案是只保留一个房间集合,让每个 State 引用该集合。

所以

public State(State another){    this.room = another.room;    ....    //for(int i=0; i<this.room.length; i++)    //    for(int j=0; j<this.room.length; j++)    //        this.room[i][j] = another.room[i][j];}

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注