Coursera 프 린스 턴 대학 알고리즘 Week 4: 8 퍼 즐 해독

작업 링크:http://coursera.cs.princeton.edu/algs4/assignments/8puzzle.html
이번 작업 의 난점 은 합 리 적 인 내부 변 수 를 구축 하 는 것 입 니 다. 특히 Solver 류 의 변 수 를 제시 에 따라 한 걸음 한 걸음 풀 면 됩 니 다.
Solver 클래스 의 변 수 는 다음 과 같 습 니 다.
        private SearchNode currentNode;
	private SearchNode currentTwinNode;
	private Stack stackBoard;

그 중에서 stackBoard 는 스 택 저장 소 를 이용 하여 처리 한 결과 집합 입 니 다.이 결과 집 은 마지막 목표 결과 에 따라 순서대로 전구 노드 를 찾 는 것 이기 때문에 스 택 을 이용 하여 결과 집의 순 서 를 바 꿀 수 있다.
SearchNode 는 노드 클래스 를 찾기 위해 서 입 니 다.이 내부 클래스 는 다음 과 같은 요 소 를 포함 합 니 다.
private final Board board;   //       
private final int moves;    //         
private SearchNode preSearcchNode = null;  //       
private final int priority;   //        

 
currentNode 는 원본 패 널 의 현재 노드 를 찾 습 니 다. currentTwinNode 는 교환 패 널 의 현재 노드 를 찾 습 니 다.수학 적 으로 증명 할 수 있 으 며, 원본 패 널 이 풀 리 지 않 으 면 패 널 을 교환 합 니 다. 해 가 있 을 거 야.그 교환 방법 은 다음 과 같다.
 
 public Board twin()                    //               。
    {
    	int i1 = 0, j1 = 0, i2 = 1, j2 = 1;
    	if (blocks[i1][j1] == BLANK) 
    	{
    		i1 = 1;
    		j1 = 0;
    	}
    	if (blocks[i2][j2] == BLANK)
    	{
    		i2 = 1;
    		j2 = 0;
    	}
    	
    	Board newBoard = swap(i1, j1, i2, j2);
    	
    	return newBoard;
    }

그 중에서 swap 는 교환 배열 에서 a [21] [j1] 과 a [22] [j2] 의 값 입 니 다. 이 교환 은 전역 적 인 것 이기 때문에 먼저 교환 배열 을 구성 하고 원래 배열 의 값 을 복사 한 다음 에 교환 작업 을 해 야 합 니 다.
또한 본 논문 의 코드 는 저장 소 에서 아직 기준 에 도달 하지 못 했 기 때문에 개선 이 필요 하 다.
import java.util.ArrayList;

public class Board {
	private final int [][]blocks;
	private static final int BLANK = 0;
	private final int N;
	public Board(int[][] blocks)           //   n*n   
	{
		if (blocks == null) 
			throw new java.lang.IllegalArgumentException("the blocks is null");
		
		N = blocks.length;
		
		this.blocks = new int[N][N];
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				this.blocks[i][j] = blocks[i][j];
			}
		}
	}
	
    public int dimension()                 //     n
    {
    	return N;  //     
    }
    
    private int getIndex(int i, int j) //        
    {
		return i * N + j + 1;
	}
   
    private int getRow(int value) //       ,       
    {
		return (value - 1) / N;
	}
     private int getCol(int value) //       ,       
    {
    	return (value -1) % N;
	}
    public int hamming()                   // hamming   =      +     
    {
    	int wrongNum = 0;
    	for (int i = 0; i < N; i++) 
			for (int j = 0; j < N; j++) 
				if (blocks[i][j] != BLANK && blocks[i][j] != getIndex(i, j)) // blocks[i][j]        
					wrongNum++;
		return wrongNum;
    }
    
    public int manhattan()                 // manhattan   =      +     
    {
    	int wrongNum = 0;
    	for (int i = 0; i < N; i++) 
    	{
    		for (int j = 0; j < N; j++) 
				if (blocks[i][j] != BLANK && blocks[i][j] != getIndex(i, j))  // blocks[i][j]        
				{
					int righti = getRow(blocks[i][j]); // blocks[i][j]         i  
					int rightj = getCol(blocks[i][j]); // blocks[i][j]         j  
					wrongNum = wrongNum + Math.abs(righti - i) + Math.abs(rightj -j);
				}
    	}
    	return wrongNum;
    }
    
    public boolean isGoal()                //          
    {
    	for (int i = 0; i < N; i++) 
			for (int j = 0; j < N; j++) 
				if (blocks[i][j] != BLANK && blocks[i][j] != getIndex(i, j))  // blocks[i][j]        
					return false;
    	return true;
    }
    
    private int[][] copy() //       
    {
    	int [][]newblocks = new int[N][N];   
    	for (int i1 = 0; i1 < N; i1++)
			for (int j1 = 0; j1 < N; j1++) 
				newblocks[i1][j1] = this.blocks[i1][j1];
    	return newblocks;
	}
    
    private Board swap(int i1, int j1, int i2, int j2) //           
    {
    	int [][]newblocks = copy();
    	int temp = newblocks[i1][j1];
    	newblocks[i1][j1] = newblocks[i2][j2];
    	newblocks[i2][j2] = temp;
    	return new Board(newblocks);
    }
    
    public Board twin()                    //               。
    {
    	int i1 = 0, j1 = 0, i2 = 1, j2 = 1;
    	if (blocks[i1][j1] == BLANK) 
    	{
    		i1 = 1;
    		j1 = 0;
    	}
    	if (blocks[i2][j2] == BLANK)
    	{
    		i2 = 1;
    		j2 = 0;
    	}
    	
    	Board newBoard = swap(i1, j1, i2, j2);
    	
    	return newBoard;
    }
    public boolean equals(Object y)        //           
    {
    	if (y == null)  
    		return false;
    	if (y == this) 
    		return true;
    	
    	if (y.getClass().isInstance(this)) // y this        
    	{
    		Board boardY = (Board) y;
    		if (boardY.N != this.N)
    			return false;
    		for (int i = 0; i < N; i++) 
    			for (int j = 0; j < N; j++) 
    				if (this.blocks[i][j] != boardY.blocks[i][j]) 
    					return false;
    	}
    	else // y this        
    	{
			return false;
		}
    	
    	return true;
    }
    public Iterable neighbors()     //        
    {
    	ArrayList boards = new ArrayList<>();
    	
    	for (int i = 0; i < N; i++) 
    	{
    		for (int j = 0; j < N; j++)
    		{
    			if (blocks[i][j] == BLANK)  //        
    			{
					//  
    				if (i > 0) 
    				{
    					Board upBoard = swap(i, j, i-1, j);
						boards.add(upBoard);
					}
    				
    				//  
    				if (i < N-1) 
    				{
    					Board lowBoard = swap(i, j, i+1, j);
    					boards.add(lowBoard);
					}
    				
    				//  
    				if (j > 0) 
    				{
    					Board leftBoard = swap(i, j, i, j-1);
    					boards.add(leftBoard);
					}
    				
    				//  
    				if (j < N-1) 
    				{
    					Board rightBoard = swap(i, j, i, j+1);
    					boards.add(rightBoard);
					}
				}
    			
			}
    		
		}
		return boards;
    }
    public String toString()               //           (          )
    {
    	StringBuilder sBuilder = new StringBuilder();
    	sBuilder.append(N + "
"); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { sBuilder.append(blocks[i][j] +"\t"); } sBuilder.append("
"); } String string = sBuilder.toString(); return string; } public static void main(String[] args) // unit tests (not graded) { int [][]blocks = new int[3][3]; blocks[0][0] = 8; blocks[0][1] = 1; blocks[0][2] = 3; blocks[1][0] = 4; blocks[1][1] = 0; blocks[1][2] = 2; blocks[2][0] = 7; blocks[2][1] = 6; blocks[2][2] = 5; Board board = new Board(blocks); System.out.println(board.manhattan()); System.out.println(board.toString()); for (Board it : board.neighbors()) { System.out.println(it.toString()); } System.out.println(board.twin().toString()); } }
import edu.princeton.cs.algs4.MinPQ;
import edu.princeton.cs.algs4.Stack;

public class Solver {
	private SearchNode currentNode;
	private SearchNode currentTwinNode;
	private Stack stackBoard;
	
	private class SearchNode implements Comparable
	{
		private final Board board;   //       
		private final int moves;    //         
		private SearchNode preSearcchNode = null;  //       
		private final int priority;   //        
		
		public SearchNode(Board board, SearchNode pNode) 
		{
			this.board = board;
			this.preSearcchNode = pNode;
			if (preSearcchNode == null) 
				moves = 0;
			else
				moves = preSearcchNode.getMoves() + 1;
			priority = board.manhattan() + getMoves();
		}
	
		public int compareTo(SearchNode otherNode) 
		{
			return Integer.compare(this.getPriority(), otherNode.getPriority());
		}
		
		public int getPriority() {
			return priority;
		}
		public Board getBoard()
		{
			return board;
		}
		public int getMoves()
		{
			return moves;
		}
		public SearchNode getPreNode() 
		{
			return preSearcchNode;
		}
		
	}
	
    public Solver(Board initial)           //           (  A*  )
    {
    	if (initial == null) 
    		throw new java.lang.IllegalArgumentException("The intial Board is null");
    	
    	currentNode = new SearchNode(initial, null);  //   
    	MinPQ minInitialPQ = new MinPQ<>();
    	minInitialPQ.insert(currentNode);
    	
    	currentTwinNode = new SearchNode(initial.twin(), null); //         
    	MinPQ minTwinNode = new MinPQ<>();
    	minTwinNode.insert(currentTwinNode);
    	
    	boolean flag = false;
    	while (flag != true) 
    	{
    		//          
    		currentNode = minInitialPQ.delMin();  //           
    		if (currentNode.getBoard().isGoal())   //   
    			flag = true;
    		else
    			putNeighborsBoardToPQ(currentNode, minInitialPQ); //          
    		
    		//             
    		currentTwinNode = minTwinNode.delMin();   //           
    		if (currentTwinNode.getBoard().isGoal()) 
    			flag = true;
			 else 
				 putNeighborsBoardToPQ(currentTwinNode, minTwinNode);     //          
		}
    }
    
    //           
    private void putNeighborsBoardToPQ(SearchNode currentNode, MinPQ pMinPQ) 
	{
		Iterable boards = currentNode.getBoard().neighbors(); //       
		for (Board neighborsBoard : boards) {
			if (currentNode.getPreNode() == null || 
					neighborsBoard.equals(currentNode.getPreNode().getBoard()) != true)   //       
				pMinPQ.insert(new SearchNode(neighborsBoard, currentNode));  //          
		}
	}
	
    public boolean isSolvable()            //         ?
    {
    	return currentNode.getBoard().isGoal();
    }
    public int moves()                     //            ;     ,  -1
    {
    	if (isSolvable()) 
    		return currentNode.getMoves();
    	else 
    		return -1;
    }
    public Iterable solution()      //         ;       
    {
    	if (isSolvable() != true) 
			return null;
    	stackBoard = new Stack<>();
    	SearchNode nowNode = currentNode;
    
    	while (nowNode != null) {
			stackBoard.push(nowNode.getBoard());
			nowNode = nowNode.getPreNode();
		}
    	
    	return stackBoard;
    		
    }
    public static void main(String[] args) // solve a slider puzzle (given below)
    {
    	int [][]blocks = new int[3][3];
    	
    	blocks[0][0] = 8;
    	blocks[0][1] = 1;
    	blocks[0][2] = 3;
    	
    	blocks[1][0] = 4;
    	blocks[1][1] = 0;
    	blocks[1][2] = 2;
    	
    	blocks[2][0] = 7;
    	blocks[2][1] = 6;
    	blocks[2][2] = 5;
    	Board board = new Board(blocks);
    	
    	Solver solver = new Solver(board);
    	System.out.println(solver.currentNode.getPreNode() == null);
    	System.out.println(solver.currentNode.getPreNode());
    	if (solver.isSolvable() != false) {
			System.out.println("this board is can't resolve");
		}
    	
    	Iterable bIterable = solver.solution();
    	System.out.println(bIterable.toString());
    	System.out.println("444");
    	
    	for (Board it : bIterable) {
    		System.out.println(it.toString());
    	}
   
    }
}

좋은 웹페이지 즐겨찾기