多執行緒解n王后問題的優化
在網上看到這個程式,作者給出的時間和我實際執行有很大差距。 他的
15皇后,用時:4903毫秒,計算結果:2279184 16皇后,用時:33265毫秒,計算結果:14772512 17皇后,用時:267460毫秒,計算結果:95815104
我的
D:\>javac EightQueen7.java D:\>java EightQueen7 解決 9皇后問題,用時:94毫秒,計算結果:352 解決 10皇后問題,用時:7毫秒,計算結果:724 解決 11皇后問題,用時:47毫秒,計算結果:2680 解決 12皇后問題,用時:131毫秒,計算結果:14200 解決 13皇后問題,用時:666毫秒,計算結果:73712 解決 14皇后問題,用時:2707毫秒,計算結果:365596 解決 15皇后問題,用時:23059毫秒,計算結果:2279184 解決 16皇后問題,用時:142386毫秒,計算結果:14772512 解決 17皇后問題,用時:1226259毫秒,計算結果:95815104
約為他的5倍。我的機器CPU是:pentium G3450 3.4Ghz
把他的程式改成二進位制位運算,速度提高了1倍。
//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 EightQueen8 { 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; static int []w =new int[300]; static int []w1=new int[300]; static int []w2=new int[300]; public EightQueenThread(short[] chess){ this.chess=chess; this.N=(short) chess.length; //init w w1 w2 for(int n=1;n<=N*N;n++) { int r=(n-1)/N+1; int c=(n-1)%N+1; //System.out.printf("%d,%d,%d,%d,%d,%d\n",n,r,c,1<<c,1<<(r+c-2),1<<(r-c+N-1)); w[n]=1<<c; w1[n]=1<<(r+c-2); w2[n]=1<<(r-c+N-1); } } @Override public Long call() throws Exception { //System.out.printf("chess[0]=%d\n",chess[0]); return putQueenAtRow(chess, (short)1,w[chess[0]+1],w1[chess[0]+1],w2[chess[0]+1]) ; } private Long putQueenAtRow(short[] chess, short row,int sw,int sw1,int sw2) { if(row==N){ //System.out.printf("find one result:%d %d %d %d\n",chess[0],chess[1],chess[2],chess[3]); return (long) 1; } short[] chessTemp=chess.clone(); long sum=0; /** * 向這一行的每一個位置嘗試排放皇后 * 然後檢測狀態,如果安全則繼續執行遞迴函式擺放下一行皇后 */ for(short i=0;i<N;i++){ //擺放這一行的皇后 chessTemp[row]=i; //if( isSafety( chessTemp,row,i) ){ int n=(row)*N+i+1; if(( w[n]& sw) ==0 &&(w1[n]& sw1)==0 && (w2[n]& sw2)==0) { //System.out.printf("n=%d,%d,%d,%d,%d,%d,%d\n",n,sw, sw1, sw2,w[n], w1[n],w2[n]); sum+=putQueenAtRow(chessTemp,(short) (row+1),sw+w[n],sw1+w1[n],sw2+w2[n]); } } 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; } } D:\>javac EightQueen8.java D:\>java EightQueen8 解決 9皇后問題,用時:16毫秒,計算結果:352 解決 10皇后問題,用時:0毫秒,計算結果:724 解決 11皇后問題,用時:48毫秒,計算結果:2680 解決 12皇后問題,用時:112毫秒,計算結果:14200 解決 13皇后問題,用時:538毫秒,計算結果:73712 解決 14皇后問題,用時:2246毫秒,計算結果:365596 解決 15皇后問題,用時:14686毫秒,計算結果:2279184 解決 16皇后問題,用時:85156毫秒,計算結果:14772512 解決 17皇后問題,用時:723597毫秒,計算結果:95815104
在一臺xeon E5420 2.5Ghz*2的機器上的結果
C:\>javac EightQueen7.java C:\>java EightQueen7 解決 9皇后問題,用時:78毫秒,計算結果:352 解決 10皇后問題,用時:31毫秒,計算結果:724 解決 11皇后問題,用時:0毫秒,計算結果:2680 解決 12皇后問題,用時:47毫秒,計算結果:14200 解決 13皇后問題,用時:203毫秒,計算結果:73712 解決 14皇后問題,用時:952毫秒,計算結果:365596 解決 15皇后問題,用時:5709毫秒,計算結果:2279184 解決 16皇后問題,用時:39531毫秒,計算結果:14772512 解決 17皇后問題,用時:330454毫秒,計算結果:95815104 C:\>javac EightQueen8.java C:\>java EightQueen8 解決 9皇后問題,用時:15毫秒,計算結果:352 解決 10皇后問題,用時:32毫秒,計算結果:724 解決 11皇后問題,用時:0毫秒,計算結果:2680 解決 12皇后問題,用時:31毫秒,計算結果:14200 解決 13皇后問題,用時:109毫秒,計算結果:73712 解決 14皇后問題,用時:577毫秒,計算結果:365596 解決 15皇后問題,用時:2699毫秒,計算結果:2279184 解決 16皇后問題,用時:17129毫秒,計算結果:14772512 解決 17皇后問題,用時:140915毫秒,計算結果:95815104
相關文章
- 多執行緒問題解釋執行緒
- 多執行緒的安全問題及解決方案執行緒
- 多執行緒併發安全問題詳解執行緒
- iOS多執行緒全套:執行緒生命週期,多執行緒的四種解決方案,執行緒安全問題,GCD的使用,NSOperation的使用iOS執行緒GC
- 多執行緒相關問題執行緒
- Java多執行緒中執行緒安全與鎖問題Java執行緒
- 多執行緒引起的效能問題分析執行緒
- WebMagic多執行緒導致註解失效問題Web執行緒
- Java多執行緒面試高配問題---多執行緒(3)🧵Java執行緒面試
- Python | 多執行緒死鎖問題的巧妙解決方法Python執行緒
- 多執行緒之8鎖問題執行緒
- 05.java多執行緒問題Java執行緒
- 多執行緒併發同步問題及解決方案執行緒
- Java中解決多執行緒資料安全問題Java執行緒
- Spring中多執行緒的使用及問題Spring執行緒
- 多執行緒的安全性問題(三)執行緒
- 多執行緒,你覺得你安全了?(執行緒安全問題)執行緒
- HashMap多執行緒併發問題分析HashMap執行緒
- Java多執行緒程式設計—鎖優化Java執行緒程式設計優化
- Faiss使用多執行緒出現的效能問題AI執行緒
- 多執行緒 日誌 和截圖的問題執行緒
- BATJ都愛問的多執行緒面試題BAT執行緒面試題
- 1 多執行緒的優缺點執行緒
- 關於js執行緒問題的解讀JS執行緒
- 5分鐘搞懂多執行緒安全問題執行緒
- 如何解決多執行緒併發問題執行緒
- 40 個 Java 多執行緒問題總結Java執行緒
- Java多執行緒和併發問題集Java執行緒
- 詳解多執行緒執行緒
- 多執行緒詳解執行緒
- java多執行緒程式設計問題以及解決辦法Java執行緒程式設計
- 多執行緒中自定義執行緒池與shiro導致的許可權錯亂問題解決執行緒
- 有個關於多執行緒的識別問題執行緒
- 多執行緒03:?執行緒傳參詳解執行緒
- 什麼是多執行緒?Python多執行緒有什麼優勢?執行緒Python
- 多執行緒筆記---鎖(Synchronized)的優化和種類執行緒筆記synchronized優化
- javascript執行緒及與執行緒有關的效能優化JavaScript執行緒優化
- N皇后問題(各種優化)優化
- 企圖使用c++執行緒解決nodejs單執行緒問題C++執行緒NodeJS