2013-04-13 2 views
0

스도쿠 문제를 해결하기 위해 Java에서 백 트랙킹 알고리즘을 구현하려고합니다.재귀 백 트랙킹 관련 문제

나는 문제가 해결 방법에 있다고 확신하지만, 두 가지 방법을 포함했다.

내가하고있는 이상한 일들 중 일부는 퍼즐의 하드 코딩 된 초기 값과 같은 요구 사항/편의성 때문일뿐입니다. 문제는 내 해결 방법의 바닥 근처에 있다고 확신하지만, 그것을 이해할 수 없다 ...

내 현재 문제는 : 첫 번째 행에서 작업 한 후 값의 잠재적 인 유효 순열을 찾은 후, 내 프로그램은 단순히 포기합니다. "ROW IS DONE"을 인쇄하는 줄의 주석 처리를 제거하면 하나의 줄 다음에 출력되고 출력은 더 이상 출력되지 않습니다. 첫 번째 행 이후에 포기하는 이유는 무엇입니까? 내 구현에 대해 다른 것이 있습니까 걱정해야합니다

편집 : 많이 변경했습니다. 아주 가까워지고 있습니다. EXHAUST가 참일 때 인쇄하면, 마지막 행을 제외한 모든 행이 풀린 퍼즐을 얻습니다. 그것은 그것이 해결되었거나 거의 해결 된 후에 모든 것을 취소하고있는 것처럼 보입니다. 나는 퍼즐이 완전히 풀린 지점에 이미 도달했을 것 같은 느낌을 갖지만 적절한 시간에 TRUE를 되돌려주지는 않습니다 ... 지금 내가 뭘 잘못하고 있니?

import java.util.ArrayList; 

class Model 
{ 
    ArrayList<View> views = new ArrayList<View>(); 
    int[][] grid = 
      { 
       {5,3,0,0,7,0,0,0,0}, 
       {6,0,0,1,9,5,0,0,0}, 
       {0,9,8,0,0,0,0,6,0}, 
       {8,0,0,0,6,0,0,0,3}, 
       {4,0,0,8,0,3,0,0,1}, 
       {7,0,0,0,2,0,0,0,6}, 
       {0,6,0,0,0,0,2,8,0}, 
       {0,0,0,4,1,9,0,0,5}, 
       {0,0,0,0,8,0,0,7,9} 
      }; 

    /** 
    * Method solve 
    * 
    * Uses a backtracking algorithm to solve the puzzle. 
    */ 
    public boolean solve(int row, int col) //mutator 
    { 
     if(exhaust(row,col)) {printGrid(); return true;} 
     int rownext = row; 
     int colnext = col+1; 
     if(colnext>8) 
     { 
      colnext = 0; 
      rownext++; 
     }   
     if(grid[row][col] != 0) solve(rownext,colnext); 
     else //is == 0 
     { 
      for(int num = 1; num <= 9; num++) 
      { 
       if(!conflict(row,col,num)) //try a non-conflicting number 
       { 
        grid[row][col] = num; 
        if(solve(rownext,colnext)) return true;      
        grid[row][col] = 0; 
       } 
      } 
     } 
     return false;  

    } 
    /** 
    * Method exhaust 
    * 
    * Iteratively searches the rest of the puzzle for empty space 
    * using the parameters as the starting point. 
    * 
    * @return true if no 0's are found 
    * @return false if a 0 is found 
    */ 
    public boolean exhaust(int row, int col) 
    { 
     for(int i = row; i <= 8; i++) 
     { 
      for(int j = col; j <= 8; j++) 
      { 
       if(grid[i][j] == 0) return false; 
      } 
     } 
     System.out.printf("Exhausted.\n"); 
     return true; 
    } 

    /** 
    * Method conflict 
    * 
    * Checks if the choice in question is valid by looking to see 
    * if the choice has already been made in the same row or col, 
    * or block. 
    * 
    * @return true if there IS a conflict 
    * @return false if there is NOT a conflict 
    */ 
    public boolean conflict(int row, int col, int num) 
    { 
     for(int j = 0; j <= 8; j++) 
     { 
      if(grid[row][j] == num) { 
       return true; 
      } 
     } 
     for(int i = 0; i <= 8; i++) 
     { 
      if(grid[i][col] == num) { 
       return true; 
      } 
     }   

     int rowstart = 0; 
     if(row>=3) rowstart = 3; 
     if(row>=6) rowstart = 6; 

     int colstart = 0; 
     if(col>=3) colstart = 3; 
     if(col>=6) colstart = 6;      

     for(int r = rowstart; r <= (rowstart + 2); r++) 
     { 
      for(int c = colstart; c <= (colstart + 2); c++) 
      { 
       if(grid[r][c] == num) { 
        return true; 
       } 
      } 
     }  
     return false; 
    } 
} 
+3

Eclipse 또는 다른 고급 IDE를 사용하는 경우 디버거로 작업을 시작하십시오. 한 단계 씩 단계별로 진행하여 프로그램에서 어떤 방향으로 나아갈 수 있는지 확인할 수 있습니다. –

+0

@ PM77-1 내 컴퓨터에서 Eclipse를 설정하려고했지만 디버거가 실제로 실행을 거부했습니다. 나는 내가 이클립스를 사용한 지난 번에 내가 윈도우를 사용할 때였다고 생각했는데 괜찮 았지만, 문제가있는 것 같았다. – GrinReaper

답변

2

앞으로 부드럽게, 행 단위로 이동하고 되돌아 가지 않았다고 가정 해보십시오. 귀하의 다음 직책은 solve(1,1);입니다. 코드를 추적 할 때 rownext에주의하십시오. 문제가 빨리 보일 것입니다. 역 추적을하지 않으면 rownext는 적어도 1의 값을 유지해야합니다.

+0

당신이 알아 차 렸던 문제를 지적했지만 문제가있다. 'exhaust()'와 함께. 또한 backtracking이 작동하는지 확신 할 수 없다. ** 편집 ** 나는 생각한다 * 역 추적이 작동하지만 왜 단락 회로에'부울 '을 반환하지 않을지 모르겠다. 그 논리? – rliu

+0

당신은 불리언 방법으로 해결을 다시 말은? 교수님이 제공 한 가짜 코드가 제안했기 때문에 나는 그것을 무효로 작성했습니다. 나는 그 방법이 더 쉬울 거라 생각했지만, 그렇지 않을 수도 있습니다. – GrinReaper

+0

나는 나를 도울 수있는 더 좋은 질문을 안다. 나는 backtracking이 어떻게 작동 할 필요가 있는지 생각해 보았다. 시도 할 공간이 더 있는지를 확인하기 만하면된다. 또는 지금까지 만들어진 모든 결정을 검증해야 하는가? 필자는 채워진 퍼즐이있는 마지막 단계를 생각하고 있었고, 모든 숫자를 확인하여 모든 것이 실제로 정상적으로되었는지를 확인하는 방법이나 어디에서 확인할 수 있는지 확실하지 않습니다. 퍼즐이 해결 중입니다 ... 편집 : 신경 쓰지 마세요. 아마도 더 완벽한 "충돌"방식을 작성해야합니다. 맞습니까? – GrinReaper