1. 程式人生 > >最強N皇后JAVA解題程式碼

最強N皇后JAVA解題程式碼

關於N皇后演算法的極限挑戰,最終很滿意

程式碼使用了“一維棋盤”,“對稱剪枝”,“遞歸回溯”,“多執行緒”等特色

最終結果:

15皇后,用時:4903毫秒,計算結果:2279184

16皇后,用時:33265毫秒,計算結果:14772512

17皇后,用時:267460毫秒,計算結果:95815104

比起我第一天寫N皇后,14皇后用時87秒的成績,提高太多了!!!

 

說好的一定要在100秒內解16皇后,終於解脫了

啥都不說了,貼上程式碼和運算成績

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

package com.newflypig.eightqueen;

import java.util.ArrayList;

import java.util.Date;

import java.util.List;

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;

 

 

public class EightQueen7 {

    private static final short K=8;     //使用常量來定義,方便之後解N皇后問題

    private static short N=0;

     

    public static void main(String[] args) throws Exception {

        for(N=9;N<=17;N++){

            long count=0;

            Date begin =new Date();

            /**

             * 初始化棋盤,使用一維陣列存放棋盤資訊

             * chess[n]=X:表示第n行X列有一個皇后

             */

             

            List<short[]> chessList=new ArrayList<short[]>(N);

            for(short i=0;i<N;i++){

                short chess[]=new short[N];

                chess[0]=i;

                chessList.add(chess);

            }

             

            short taskSize =(short)( N/2+(N%2==1?1:0) );

            // 建立一個執行緒池

            ExecutorService pool = Executors.newFixedThreadPool(taskSize);

            // 建立多個有返回值的任務

            List<Future<Long>> futureList = new ArrayList<Future<Long>>(taskSize);

            for (int i = 0; i < taskSize; i++) {

                Callable<Long> c = new EightQueenThread(chessList.get(i));

                // 執行任務並獲取Future物件

                Future<Long> f = pool.submit(c);

                futureList.add(f);

            }

            // 關閉執行緒池

            pool.shutdown();

             

            for(short i=0; i<(short) (taskSize - (N%2==1?1:0)); i++){             

                count+=futureList.get(i).get();

            }

            count=count*2;

            if(N%2==1)

                count+=futureList.get(N/2).get();

             

            Date end =new Date();

            System.out.println("解決 " +N+ "皇后問題,用時:" +String.valueOf(end.getTime()-begin.getTime())+ "毫秒,計算結果:"+count);

        }

    }

}

 

class EightQueenThread implements Callable<Long>{

    private short[] chess;

    private short N;

     

    public EightQueenThread(short[] chess){

        this.chess=chess;

        this.N=(short) chess.length;

    }

     

     

    @Override

    public Long call() throws Exception {

        return putQueenAtRow(chess, (short)1) ;

    }

 

 

    private Long putQueenAtRow(short[] chess, short row) {

        if(row==N){

            return (long1;

        }

         

        short[] chessTemp=chess.clone();

        long sum=0;

        /**

         * 向這一行的每一個位置嘗試排放皇后

         * 然後檢測狀態,如果安全則繼續執行遞迴函式擺放下一行皇后

         */

        for(short i=0;i<N;i++){

            //擺放這一行的皇后

            chessTemp[row]=i;

             

            if( isSafety( chessTemp,row,i) ){

                sum+=putQueenAtRow(chessTemp,(short) (row+1));

            }

        }

         

        return sum;

    }

     

    private static boolean isSafety(short[] chess,short row,short col) {

        //判斷中上、左上、右上是否安全

        short step=1;

        for(short i=(short) (row-1);i>=0;i--){

            if(chess[i]==col)   //中上

                return false;

            if(chess[i]==col-step)  //左上

                return false;

            if(chess[i]==col+step)  //右上

                return false;

             

            step++;

        }

         

        return true;

    }

}

 

 

 

 

這是四天前的成績:

 

確實有了很大的提升!