1

プログラムを実行すると、Knights Tour が見つからず、StackOverflow エラーが発生します。これを引き起こしている原因と、実際に Knights Tour を見つけてこのエラーを取り除くためにコードを変更する方法を教えてください。プロジェクトは私の CS280 クラスのためのもので、金曜日に予定されています。助けてください。ありがとう!!

public class KnightsTourDriver {
    public static void main (String[]args) {
        KnightsTour tour1 = new KnightsTour;
        tour1.findTour(1);
        tour1.displayTour();
    }
}  



import java.util.Arrays;
class KnightsTour
{

    static int the_board[][] = new int[8][8];
    int the_tour[][] = new int [8][8];
    int k,moves = 0;
    int x = 0, y = 0; 
    int z, j = 1;
    boolean tour_found, isSafe;

        //fills 2D array with 0's
        public KnightsTour()
        {
            for (int i = 0; i < 8; i++) 
                {
                 for (int r = 0; r < 8; r++) 
                    {
                            the_board[i][r] = 0;
                        }
                }
        }
        /*recursive method, checks how many moves were made if 16 were made tour finished, 
        else if not moves knight checks if the move is valid if not back tracks*/
        public void findTour(int q)
        {

            if(moves == 64)
                {
                    tour_found = true;
                }

            else 
                move(q); 

            if(isSafe == true)
                    {
                        findTour(q++);
                        moves++;
                    }
            else
                if(isSafe == false)
                    {
                        findTour(q*(-1));
                        moves--;
                    }
        }
        //used to keep prevent arrayindexoutofbounds error
        public boolean arrayInBounds(int x, int y)
        { 
        if(x < 8 && y < 8 && x >= 0 && y >= 0)
                {
                    return true;
                }
            else return false;
        }
        /*move method uses switch statement to decide which move the knight should make
        based on a case number, negative case numbers back track knight. if statement checks
        if the current array element is empty and the index is inbounds*/
        public void move(int a)
        {

            switch (a)
            {
               case 1:
                if(arrayInBounds(x+2, y+1) == true){
                   if(the_board[x+2][y+1] != 0){                          
                        the_board[x+2][y+1]=j;
                            j++;
                            break;
                        }
                        else isSafe = false;
                        break;
                    }
                else isSafe = false;
               case 2:
                if (arrayInBounds(x+1, y+2) == true){
                    if(the_board[x+1][y+2] != 0){               
                            the_board[x+1][y+2]=j;
                            j++;
                            break;
                        }
                        else isSafe = false;
                        break;
                }
                else isSafe = false;
               case 3:
                 if(arrayInBounds(x-1, y+2) == true){
                   if(the_board[x-1][y+2] != 0){           
                            the_board[x-1][y+2]=j;
                            j++;
                            break;
                        }
                        else isSafe = false;
                        break;
                 }
                else isSafe = false;
               case 4:
                if (arrayInBounds(x-2, y+1) == true){
                    if(the_board[x-2][y+1] != 0){           
                            the_board[x-2][y+1]=j;
                            j++;
                            break;
                        }
                        else isSafe = false;
                        break;
                }
                else isSafe = false;
               case 5:
                if(arrayInBounds(x-2, y-1) == true){
                    if(the_board[x-2][y-1] != 0){           
                            the_board[x-2][y-1]=j;
                            j++;
                            break;
                        }
                        else isSafe = false;
                        break;
                }
                else isSafe = false;
               case 6:
                if(arrayInBounds(x-1, y-2) == true){
                        if(the_board[x-1][y-2] != 0){                    
                            the_board[x-1][y-2]=j;
                            j++;
                            break;
                        }
                        else isSafe = false;
                        break;
            }
                else isSafe = false;
               case 7:
                 if(arrayInBounds(x+1, y-2) == true){
                    if(the_board[x+1][y-2] != 0){          
                            the_board[x+1][y-2]=j;
                            j++;
                            break;
                        }
                        else isSafe = false;
                        break;
                 }
                 else isSafe = false;
               case 8:
                if(arrayInBounds(x+2, y-1) == true){
                 if(the_board[x+2][y-1] != 0){
                            the_board[x+2][y-1]=j;
                            j++;
                            break;
                        }
                        else isSafe = false;
                        break;
                }
                else isSafe = false;
               case -1:
                      j--;
                      tryNextMove(a);
                      break;
                    case -2:
                        j--;
                        tryNextMove(a);
                        break;
                    case -3:
                      j--;
                      tryNextMove(a);
                      break;
                    case -4:
                      j--;
                      tryNextMove(a);
                      break;
                  case -5:
                     j--;
                      tryNextMove(a);
                      break;
                    case -6:
                      j--;
                      tryNextMove(a);
                      break;
                    case -7:
                      j--;
                      tryNextMove(a);
                      break;
                   case -8:
                      j--;
                      tryNextMove(a);
                      break;
             }
        }
        public void tryNextMove(int m)
        {
            move(m++);
        }
        //for loop to display tour once found//         
        public void displayTour()
        {
            int v = 1;
            for (int i = 0; i < 8; i++) 
                {
                 for (int e = 0; e < 8; e++) 
                    {               
                                if(v % 8 == 0)
                                {
                                    System.out.print(the_board[i][e] + "\t");
                                    System.out.println("\n");
                                } 
                        else    
                            System.out.print(the_board[i][e] + "\t");
                            v++;                
                        }
                }
        }
}
4

2 に答える 2

1

アルゴリズムが再帰呼び出しの深さを本当に必要とする場合は、起動時に引数を JVM に渡して、スタック サイズの制限を増やすことができます: -Xss4m

もちろん、アルゴリズムが無制限に再帰する場合、これは問題を遅らせるだけです。

于 2014-02-25T15:02:17.770 に答える
0

switch の case ステートメントにいくつかの休憩が必要です。そうしないと、失敗します。

于 2014-02-25T15:11:51.377 に答える