자바 콘솔 애플리케이션에서 스도쿠를 해결하기 위해 역 추적 알고리즘을 구현하려고했습니다. 전에는 알고리즘을 구현 한 적도 없었고, 아마 몇 편의 유튜브 비디오 만 보아도 충분하지 않았습니다. 왜냐하면 그것이 제대로 작동하지 않는 것 같기 때문입니다.스도쿠를 해결하기위한 역 추적 알고리즘
온라인으로 찾은 실제 스도쿠로 보드를 수동으로 채웠습니다. 그러나 첫 번째 사각형을지나 가지 않습니다. 처음에는 두 번 for-loop에서 모든 것을 중첩하려했지만 그 중 하나는 작동하지 않습니다.
유효한 이동 방법을 올바르게 테스트 했으므로 문제가 분명히 없습니다. 감사합니다.
public class Sudoku {
public static int[][] createBoard(int n)
{
int[][] board = new int[n][n];
for (int i=0; i<board.length; i++)
for (int j=0; j<board[i].length; j++)
board[i][j]=0;
return board;
}
public static void printBoard(int[][] b)
{
int buffer=(int)Math.sqrt(b.length);
String btm=new String(new char[buffer*buffer*3+buffer+1]).replace("\0", "_"); // fitting for all board size
for (int i=0; i<b.length; i++)
{
if (i%buffer==0)
System.out.println(btm);
for (int j=0; j<b[i].length; j++)
{
if (j%buffer==0)
System.out.print("|");
if (b[i][j]==0)
System.out.print(" _ ");
else
System.out.print(" " + b[i][j] + " ");
}
System.out.println("|");
}
System.out.println(btm);
}
// returns true if a number can be inserted in a row.
public static boolean checkLegalRow(int[][] b, int row, int num)
{
for (int i=0; i<b.length; i++)
{
if (b[row][i]==num)
return false;
}
return true;
}
// returns true if a number can be inserted in a column.
public static boolean checkLegalCol(int[][] b, int col, int num)
{
for (int i=0; i<b.length; i++)
{
if (b[i][col]==num)
return false;
}
return true;
}
//returns true if number can be inserted in its NxN box
public static boolean checkLegalBox(int[][] b, int row, int col, int num)
{
int buffer=(int)Math.sqrt(b.length);
for (int i=0, adjRow=row-(row%buffer); i<buffer; i++, adjRow++)
{
for (int j=0, adjCol=col-(col%buffer); j<buffer; j++, adjCol++)
{
if (b[adjRow][adjCol]==num)
return false;
}
}
return true;
}
public static boolean legalMove(int[][] b, int row, int col, int num)
{
return checkLegalRow(b,row,num) && checkLegalCol(b,col,num) && checkLegalBox(b,row,col,num) && b[row][col]==0;
}
public static void solveBacktrack(int[][] b, int row, int col)
{
for (int k=1; k<=b.length; k++)
{
if (legalMove(b,row,col,k))
{
b[row][col]=k;
if (row==b.length-1 && col==b.length-1)
printBoard(b);
else
{
//printBoard(b);
if (col==b.length-1)
solveBacktrack(b,row+1,0);
else
solveBacktrack(b,row,col+1);
}
}
}
}
public static void main(String[] args)
{
int[][] board=createBoard(9);
board[0][1]=4; board[1][0]=6; board[2][1]=8; board[2][2]=9; board[0][3]=6; board[2][5]=3; board[1][7]=3;
board[1][8]=1; board[3][3]=4;
board[3][0]=2; board[3][2]=1; board[3][4]=5; board[3][7]=7; board[3][8]=8; board[4][1]=5;
board[4][3]=3; board[4][5]=7; board[5][0]=3; board[5][1]=6; board[5][4]=2; board[5][5]=8; board[5][8]=5;
board[6][3]=1; board[6][6]=6; board[6][7]=4; board[7][0]=4; board[7][1]=3; board[7][8]=9; board[8][2]=6;
board[8][5]=9;
printBoard(board);
solveBacktrack(board,0,0);
}
}
당신의 논리를 말해주십시오. 난 당신이 단지 상자에 대한 숫자의 유효성을 반복하고 해당 번호가 이미 존재하는지 여부를 확인하는 것으로 잘못 판단한 것 같습니다. 이렇게 생각하십시오. 처음에는 첫 번째 행, 첫 번째 열 및 첫 번째 블록에 숫자 9가 없습니다. 따라서 논리에 따르면이 블록의 숫자는 9입니다. 그러나 첫 번째 행, 두 번째 열 및 첫 번째 블록에도 9가없는 경우가있을 수 있습니다. –
이것은 복잡한 알고리즘이므로 많은 계산이 필요합니다. –
춤 필요 링크 : https://www.ocf.berkeley.edu/~jchu/publicportal/sudoku/sudoku.paper.html –