线程“main”java.lang.StackOverflowError问题中的异常

时间:2014-11-21 01:50:25

标签: java artificial-intelligence

我需要你的帮助。 我不知道为什么我的代码在维度为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("There is no solution under the constraint of  maximum number of dirty slots");
        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;


    // checking valid moves

    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("The number of expanded nodes is: "+num_of_expanded_states);

}

public String calculatePath(State state){
    if(state.father==null){
        return path;
    }
    return calculatePath(state.father).concat(state.action);

}
}

这是州的代码:

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) 


there is a lot lines like the above one so i can't include all of them

1 个答案:

答案 0 :(得分:1)

您可以修复stackover-flow问题,但将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 [recuse] queue = [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队列中的房间,您将看到我的意思。

我建议这样做的答案是只有一个房间集合,并让每个州都参考该集合。

所以

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];
}