计算机解决数独,只是网上存个档,勿喷

计算机解决数独,只是网上存个档,勿喷

解决各种数独 9x9  16x16
16x16的需要大量时间。

初始 0 表示 空

代码

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicLong;
 
/**
 * 数独
 * 
 * @author zlb
 */
public class ShuDu {
    private final int DD_SIZE;
    private final int SQRT_SIZE;
    private final int[][] dd;
 
    public ShuDu(String filePath) {
        this(filePath, 9);
    }
 
    public ShuDu(String filePath, int size) {
        DD_SIZE = size;
        SQRT_SIZE = (int) Math.sqrt(size);
        dd = new int[DD_SIZE][DD_SIZE];
        if (SQRT_SIZE * SQRT_SIZE != DD_SIZE) {
            throw new IllegalArgumentException(" size error !" + size);
        }
        BufferedReader in = null;
        int vv = 0;
        int i = 0;
        try {
            in = new BufferedReader(new FileReader(filePath));
            String line;
            for (i = 0; i < DD_SIZE; i++) {
                while (null != (line = in.readLine())) {
                    line = line.trim();
                    if (!line.isEmpty()) {
                        break;
                    }
                }
                if(null !=line){
                    line = line.replaceAll("\\s{2,}", " ");
                    String[] cc = line.split(" ");
                    for (int j = 0; j < cc.length; j++) {
                        vv = Integer.valueOf(cc[j]);
                        dd[i][j] = vv;
                    }
                }
            }
        } catch (Exception e) {
            throw new IllegalArgumentException("参数异常 :filePath= " + filePath
                    + " : " + i, e);
        } finally {
            if (null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
        }
    }
 
    public int[][] getDd() {
        return dd;
    }
 
    public void show(int[][] values) {
        System.out.println("------------------------------------");
        for (int i = 0; i < values.length; i++) {
            for (int j = 0; j < values[i].length; j++) {
                System.out.print(String.format("%-4d", values[i][j]));
            }
            System.out.println();
        }
        System.out.println("\n====================================");
    }
 
    public boolean isFormDD(int[][] values) {
        for (int i = 0; i < DD_SIZE; i++) {
            for (int j = 0; j < DD_SIZE; j++) {
                if (0 != dd[i][j] && dd[i][j] != values[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }
 
    public int check(int[][] values) {
        int result = 0;
        for (int i = 0; i < DD_SIZE; i++) {// 初始化
            for (int j = 0; j < DD_SIZE; j++) {
                if (0 != dd[i][j] && dd[i][j] != values[i][j]) {
                    result += 1;
                    continue;
                }
                if (check(values, i, j) > 0) {
                    result++;
                }
            }
        }
        return result;
    }
 
    protected int check(int[][] values, int row, int col) {
        if (0 == values[row][col]) {
            return 1;
        }
        int vv = values[row][col];
        int j = row / SQRT_SIZE * SQRT_SIZE;
        int k = col / SQRT_SIZE * SQRT_SIZE;
        for (int i = 0; i < DD_SIZE; i++) {// check row
            if (i != row && 0 == values[i][col] && vv == values[i][col]) {
                return 2;
            }
            if (i != col && 0 == values[row][i] && vv == values[row][i]) {
                return 3;
            }
            if (row != (j + i / SQRT_SIZE) && col != (k + i % SQRT_SIZE)) {
                if (0 != values[j + i / SQRT_SIZE][k + i % SQRT_SIZE]
                        && vv == values[j + i / SQRT_SIZE][k + i % SQRT_SIZE]) {
                    return 4;
                }
            }
        }
        return 0;
    }
 
    public int[][] exhaustiveAttack() {
        int[][] tmp = new int[DD_SIZE][DD_SIZE];
        for (int i = 0; i < DD_SIZE; i++) {// 初始化
            for (int j = 0; j < DD_SIZE; j++) {
                tmp[i][j] = dd[i][j];
            }
        }
        if (solve(tmp, 0, 0)) {
            System.out.println("solve & isFormDD  == " + isFormDD(tmp));
        }
        return tmp;
    }
 
    protected AtomicLong callTime = new AtomicLong();
 
    protected boolean solve(int[][] sk, int row, int col) {
        long tmp = callTime.incrementAndGet();
        if (tmp % 10000000 == 0) {
            System.out.println(String
                    .format("%s do [%2s - %2s]", tmp, row, col));
        }
        if (col >= DD_SIZE) {
            col = 0;
            row++;
        }
        if (row >= DD_SIZE)
            return true;
 
        if (sk[row][col] != 0)
            return solve(sk, row, ++col); // 若当前格子已有解则进行下一个格子的运算.
 
        int sqrt_row = row / SQRT_SIZE * SQRT_SIZE;
        int sqrt_col = col / SQRT_SIZE * SQRT_SIZE;
        for (int i = 0; i < DD_SIZE; i++) {
            int vv = i + 1;
            for (int j = 0; j < DD_SIZE; j++) { // 非当前节点不在行列及宫中
                if (row != j && sk[j][col] == vv) {
                    vv = 0;
                    break;
                }
                if (col != j && sk[row][j] == vv) {
                    vv = 0;
                    break;
                }
                if ((row != (sqrt_row + j / SQRT_SIZE) && col != (sqrt_col + j
                        % SQRT_SIZE))
                        && vv == sk[sqrt_row + j / SQRT_SIZE][sqrt_col + j
                                % SQRT_SIZE]) {
                    vv = 0;
                    break;
                }
            }
            sk[row][col] = vv;
            if (vv > 0 && solve(sk, row, col + 1)) {
                return true;
            }
        }
        sk[row][col] = 0;
        return false;
    }
 
    public static void main(String[] args) {
        new ShuDu("./sd/jn1.txt").report();
    }
 
    public void report() {
        show(dd);
        System.out.println("is null : " + check(dd));
        long time = System.currentTimeMillis();
        int[][] result = exhaustiveAttack();
        show(result);
        time = System.currentTimeMillis() - time;
        String msg = String.format("ok[ %s ] time[ %s ms ] call[ %s ]",
                check(result), time, callTime.get());
        System.out.println(msg);
    }
}

示例输入 9*9

9 0 6 0 1 3 0 0 8
0 5 8 0 0 0 0 9 0
0 3 0 0 0 0 0 1 0
0 6 0 8 0 0 9 2 0
0 0 3 4 0 9 1 0 0
0 4 9 0 0 6 0 3 0
0 9 0 0 0 0 0 8 0
0 1 0 0 0 0 6 7 0
4 0 0 9 6 0 3 0 1

示例 16*16

1   0   0   0   11  7   0   0   0   0   13  2   0   0   0   10 
0   0   0   12  4   0   0   8   10  0   0   3   5   0   0   0  
0   0   5   4   0   0   16  0   0   9   0   0   6   3   0   0  
0   16  14  0   0   10  0   13  1   0   11  0   0   15  2   0  
7   15  0   0   8   0   0   0   0   0   0   12  0   0   16  1  
14  0   0   3   0   0   0   0   0   0   0   0   4   0   0   9  
0   0   13  0   0   0   1   2   3   4   0   0   0   6   0   0  
0   1   0   11  0   0   5   6   7   8   0   0   12  0   13  0  
0   2   0   6   0   0   9   10  11  12  0   0   16  0   5   0  
0   0   1   0   0   0   13  14  15  16  0   0   0   9   0   0  
11  0   0   13  0   0   0   0   0   0   0   0   10  0   0   4  
12  14  0   0   1   0   0   0   0   0   0   7   0   0   15  3  
0   6   16  0   0   12  0   15  13  0   4   0   0   11  10  0  
0   0   4   9   0   0   11  0   0   7   0   0   14  5   0   0  
0   0   0   5   14  0   0   4   16  0   0   6   7   0   0   0  
13  0   0   0   10  3   0   0   0   0   12  14  0   0   0   15

猜你喜欢

转载自my.oschina.net/u/727875/blog/1826085