15个难题解决方案(由我自己输入)Astar解决方案

时间:2019-12-04 19:47:04

标签: java puzzle 8-puzzle

我正在解决这个难题,但是我的问题是,当我想要解决自己的难题时,它将解决一个随机难题。这是我的主要功能,我要在其中打印通过A * star算法解决的难题。

public static void main(String[] args) {
        FifteenPuzzle p = new FifteenPuzzle();
        p.shuffle(70);  
        System.out.println("Shuffled board:");
        p.show();

        List<FifteenPuzzle> solution;

        System.out.println("Solving with A*");
        solution = p.aStarSolve();
        showSolution(solution);

        System.out.println("Solving with Dijkstra");
        solution = p.dijkstraSolve();
        showSolution(solution);
    }

这是我的FifteenPuzzle类,我在其中创建我的难题

public class FifteenPuzzle {

  private class TilePos {
        public int x;
        public int y;

        public TilePos(int x, int y) {
            this.x=x;
            this.y=y;
        }

    }

    public final static int DIMS=4;
    private int[][] tiles;
    private int display_width;
    private TilePos blank;

    public FifteenPuzzle() {
        tiles = new int[DIMS][DIMS];
        int cnt=1;
        for(int i=0; i<DIMS; i++) {
            for(int j=0; j<DIMS; j++) {
                tiles[i][j]=cnt;
                cnt++;
            }
        }
        display_width=Integer.toString(cnt).length();

        // init blank
        blank = new TilePos(DIMS-1,DIMS-1);
        tiles[blank.x][blank.y]=0;
    }

    public final static FifteenPuzzle SOLVED=new FifteenPuzzle();


    public FifteenPuzzle(FifteenPuzzle toClone) {
        this();  // chain to basic init
        for(TilePos p: allTilePos()) { 
            tiles[p.x][p.y] = toClone.tile(p);
        }
        blank = toClone.getBlank();
    }

    public List<TilePos> allTilePos() {
        ArrayList<TilePos> out = new ArrayList<TilePos>();
        for(int i=0; i<DIMS; i++) {
            for(int j=0; j<DIMS; j++) {
                out.add(new TilePos(i,j));
            }
        }
        return out;
    }


    public int tile(TilePos p) {
        return tiles[p.x][p.y];
    }


    public TilePos getBlank() {
        return blank;
    }


    public TilePos whereIs(int x) {
        for(TilePos p: allTilePos()) { 
            if( tile(p) == x ) {
                return p;
            }
        }
        return null;
    }


    @Override
    public boolean equals(Object o) {
        if(o instanceof FifteenPuzzle) {
            for(TilePos p: allTilePos()) { 
                if( this.tile(p) != ((FifteenPuzzle) o).tile(p)) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }


    @Override 
    public int hashCode() {
        int out=0;
        for(TilePos p: allTilePos()) {
            out= (out*DIMS*DIMS) + this.tile(p);
        }
        return out;
    }


    public void show() {
        System.out.println("-----------------");
        for(int i=0; i<DIMS; i++) {
            System.out.print("| ");
            for(int j=0; j<DIMS; j++) {
                int n = tiles[i][j];
                String s;
                if( n>0) {
                    s = Integer.toString(n);    
                } else {
                    s = "";
                }
                while( s.length() < display_width ) {
                    s += " ";
                }
                System.out.print(s + "| ");
            }
            System.out.print("\n");
        }
        System.out.print("-----------------\n\n");
    }


    public List<TilePos> allValidMoves() {
        ArrayList<TilePos> out = new ArrayList<TilePos>();
        for(int dx=-1; dx<2; dx++) {
            for(int dy=-1; dy<2; dy++) {
                TilePos tp = new TilePos(blank.x + dx, blank.y + dy);
                if( isValidMove(tp) ) {
                    out.add(tp);
                }
            }
        }
        return out;
    }


    public boolean isValidMove(TilePos p) {
        if( ( p.x < 0) || (p.x >= DIMS) ) {
            return false;
        }
        if( ( p.y < 0) || (p.y >= DIMS) ) {
            return false;
        }
        int dx = blank.x - p.x;
        int dy = blank.y - p.y;
        if( (Math.abs(dx) + Math.abs(dy) != 1 ) || (dx*dy != 0) ) {
            return false;
        }
        return true;
    }


    public void move(TilePos p) {
        if( !isValidMove(p) ) {
            throw new RuntimeException("Invalid move");
        }
        assert tiles[blank.x][blank.y]==0;
        tiles[blank.x][blank.y] = tiles[p.x][p.y];
        tiles[p.x][p.y]=0;
        blank = p;
    }


    /**
     * returns a new puzzle with the move applied
     * @param p
     * @return
     */
    public FifteenPuzzle moveClone(TilePos p) {
        FifteenPuzzle out = new FifteenPuzzle(this);
        out.move(p);
        return out;
    }


    public void shuffle(int howmany) {
        for(int i=0; i<howmany; i++) {
            List<TilePos> possible = allValidMoves();
            int which =  (int) (Math.random() * possible.size());
            TilePos move = possible.get(which);
            this.move(move);
        }
    }


    public void shuffle() {
        shuffle(DIMS*DIMS*DIMS*DIMS*DIMS);
    }


    public int numberMisplacedTiles() {
        int wrong=0;
        for(int i=0; i<DIMS; i++) {
            for(int j=0; j<DIMS; j++) {
                if( (tiles[i][j] >0) && ( tiles[i][j] != SOLVED.tiles[i][j] ) ){
                    wrong++;
                }
            }
        }
        return wrong;
    }


    public boolean isSolved() {
        return numberMisplacedTiles() == 0;
    }

这就是我用来显示解决方案的地方。

private static void showSolution(List<FifteenPuzzle> solution) {
        if (solution != null ) {
            System.out.printf("Success!  Solution with %d moves:\n", solution.size());
            for( FifteenPuzzle sp: solution) {
                sp.show();
            }
        } else {
            System.out.println("Did not solve. :(");            
        }
    }

0 个答案:

没有答案