多執行緒解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
相關文章
- 利用C++多執行緒優化n王后問題C++執行緒優化
- 多執行緒結合經典位運算解n王后問題的優化執行緒優化
- 多執行緒問題解釋執行緒
- 多執行緒問題執行緒
- java多執行緒執行問題Java執行緒
- 多執行緒鎖的問題執行緒
- 【java 多執行緒】多執行緒併發同步問題及解決方法Java執行緒
- 多執行緒的安全問題及解決方案執行緒
- Java多執行緒面試高配問題---多執行緒(3)🧵Java執行緒面試
- 使用執行緒池優化多執行緒程式設計執行緒優化程式設計
- 多執行緒併發安全問題詳解執行緒
- 多執行緒程式設計,處理多執行緒的併發問題(執行緒池)執行緒程式設計
- 多執行緒-執行緒安全問題的產生原因分析以及同步程式碼塊的方式解決執行緒安全問題執行緒
- 多執行緒相關問題執行緒
- Hibernate 多執行緒問題!執行緒
- iOS多執行緒全套:執行緒生命週期,多執行緒的四種解決方案,執行緒安全問題,GCD的使用,NSOperation的使用iOS執行緒GC
- 多執行緒-多執行緒常見的面試題執行緒面試題
- Java多執行緒中執行緒安全與鎖問題Java執行緒
- WebMagic多執行緒導致註解失效問題Web執行緒
- 多執行緒引起的效能問題分析執行緒
- seam中使用多執行緒的問題執行緒
- 一個多執行緒的PushbackInputStream問題執行緒
- java多執行緒問題 多核cpu遇上java多執行緒,求解釋Java執行緒
- Java中多執行緒的概述、實現方式、執行緒控制、生命週期、多執行緒程式練習、安全問題的解決...Java執行緒
- 多執行緒之8鎖問題執行緒
- 05.java多執行緒問題Java執行緒
- 簡單的執行緒同步問題:兩個執行緒交替執行N次【Synchronized、Lock、ArrayBlockingQueue】執行緒synchronizedBloC
- 多執行緒-生產者消費者問題程式碼2並解決執行緒安全問題執行緒
- 多執行緒下的程式同步(執行緒同步問題總結篇)執行緒
- 多執行緒併發同步問題及解決方案執行緒
- Java中解決多執行緒資料安全問題Java執行緒
- BATJ都愛問的多執行緒面試題BAT執行緒面試題
- 多執行緒的安全性問題(三)執行緒
- objective-c 多執行緒注意的問題Object執行緒
- 請教一個多執行緒的問題執行緒
- 多執行緒,你覺得你安全了?(執行緒安全問題)執行緒
- Python | 多執行緒死鎖問題的巧妙解決方法Python執行緒
- Java多執行緒程式設計—鎖優化Java執行緒程式設計優化