ソースコード
今回の連載 python/pypy/codonのソースコードディレクトリはこちら
https://github.com/suzukiiichiro/N-Queens/tree/master/10Bit_Python
インストールなどの構築はこちら
Nクイーン問題(66) Python-codonで高速化
https://suzukiiichiro.github.io/posts/2025-03-05-01-n-queens-suzuki/
最適化について
今回の修正点は1箇所です。
def nqueens()
関数の中のlim
です。
lim:int=size if row!=0 else (size+1) //2
これはミラー処理で、盤面の半分だけを処理します。
結局版全体を処理するのと、半分だけを処理してsymmetryops()
で対象解除を行い、その判定処理の結果を、関数の最後でカウントを二倍しているわけです。
def symmetryops(self,size:int)->int:
nequiv:int=0
:
:
return nequiv*2
symmetryops()
、それにまつわる回転周りの関数は、ビット処理に進むことで更に簡潔に、そして高速な関数に書き換わっていきます。
ソースコード
from datetime import datetime
# pypyを使う場合はコメントを解除
# pypyで再帰が高速化できる
# import pypyjit
# pypyjit.set_param('max_unroll_recursion=-1')
class NQueens05:
total:int
unique:int
aboard:list[int]
fa:list[int]
fb:list[int]
fc:list[int]
trial:list[int]
scratch:list[int]
def __init__(self):
pass
def init(self,size:int)->None:
self.total=0
self.unique=0
self.aboard=[i for i in range(size)]
self.fa=[0 for i in range(2*size-1)]
self.fb=[0 for i in range(2*size-1)]
self.fc=[0 for i in range(2*size-1)]
self.trial=[0 for i in range(size)]
self.scratch=[0 for i in range(size)]
def rotate(self,chk:list[int],scr:list[int],_n:int,neg:int)->None:
incr:int=0
k:int=0
if neg:
k=0
else:
k=_n-1
if neg:
incr=1
else:
incr-=1
for i in range(_n):
scr[i]=chk[k]
k+=incr
k=_n-1 if neg else 0
for i in range(_n):
chk[scr[i]]=k
k-=incr
def vmirror(self,chk:list[int],neg:int)->None:
for i in range(neg):
chk[i]=(neg-1)-chk[i]
def intncmp(self,_lt:list[int],_rt:list[int],neg)->int:
rtn:int=0
for i in range(neg):
rtn=_lt[i]-_rt[i]
if rtn!=0:
break
return rtn
def symmetryops(self,size:int)->int:
nequiv:int=0
for i in range(size):
self.trial[i]=self.aboard[i]
# 90
self.rotate(self.trial,self.scratch,size,0)
k:int=self.intncmp(self.aboard,self.trial,size)
if k>0:
return 0
if k==0:
nequiv=1
else:
#180
self.rotate(self.trial,self.scratch,size,0)
k=self.intncmp(self.aboard,self.trial,size)
if k>0:
return 0
if k==0:
nequiv=2
else:
#270
self.rotate(self.trial,self.scratch,size,0)
k=self.intncmp(self.aboard,self.trial,size)
if k>0:
return 0
nequiv=4
for i in range(size):
self.trial[i]=self.aboard[i]
# 垂直反転
self.vmirror(self.trial,size)
k=self.intncmp(self.aboard,self.trial,size)
if k>0:
return 0
# 90
if nequiv > 1:
self.rotate(self.trial,self.scratch,size,1)
k=self.intncmp(self.aboard,self.trial,size)
if k>0:
return 0
# 180
if nequiv>2:
self.rotate(self.trial,self.scratch,size,1)
k=self.intncmp(self.aboard,self.trial,size)
if k>0:
return 0
#270
self.rotate(self.trial,self.scratch,size,1)
k=self.intncmp(self.aboard,self.trial,size)
if k>0:
return 0
return nequiv*2
def nqueens(self,row:int,size:int)->None:
if row==size-1:
if self.fb[row-self.aboard[row]+size-1] or self.fc[row+self.aboard[row]]:
return
stotal:int=self.symmetryops(size)
if stotal!=0:
self.unique+=1
self.total+=stotal
else:
lim:int=size if row!=0 else (size+1) //2
tmp:int
for i in range(row,lim):
tmp=self.aboard[i]
self.aboard[i]=self.aboard[row]
self.aboard[row]=tmp
if self.fb[row-self.aboard[row]+size-1]==0 and self.fc[row+self.aboard[row]]==0:
self.fb[row-self.aboard[row]+size-1]=self.fc[row+self.aboard[row]]=1
self.nqueens(row+1,size)
self.fb[row-self.aboard[row]+size-1]=self.fc[row+self.aboard[row]]=0
tmp=self.aboard[row]
for i in range(row+1,size):
self.aboard[i-1]=self.aboard[i]
self.aboard[size-1]=tmp
def main(self)->None:
min:int=4
max:int=18
print(" N: Total Unique hh:mm:ss.ms")
for size in range(min,max):
self.init(size)
start_time=datetime.now()
self.nqueens(0,size)
time_elapsed=datetime.now()-start_time
text = str(time_elapsed)[:-3]
print(f"{size:2d}:{self.total:13d}{self.unique:13d}{text:>20s}")
# 5.枝刈りと最適化
# $ python <filename>
# $ pypy <fileName>
# $ codon build -release <filename>
# 15: 2279184 285053 0:00:15.677
if __name__=='__main__':
NQueens05().main();
実行結果
$ codon build -release 05Python_optimize.py && ./05Python_optimize
N: Total Unique hh:mm:ss.ms
4: 2 1 0:00:00.000
5: 10 2 0:00:00.000
6: 4 1 0:00:00.000
7: 40 6 0:00:00.000
8: 92 12 0:00:00.000
9: 352 46 0:00:00.000
10: 724 92 0:00:00.001
11: 2680 341 0:00:00.009
12: 14200 1787 0:00:00.040
13: 73712 9233 0:00:00.217
14: 365596 45752 0:00:01.196
15: 2279184 285053 0:00:08.156
16: 14772512 1846955 0:00:51.271
17: 95815104 11977939 0:06:34.021
前の章の結果と比べると半分以下の処理時間となっています。
17: 95815104 11977939 0:14:59.143
次の章では、ビット版のバックトラッキングのcodon化を具体的にご説明していきます。
ソースコード
今回の連載 python/pypy/codonのソースコードディレクトリはこちら
https://github.com/suzukiiichiro/N-Queens/tree/master/10Bit_Python
Nクイーン問題 過去記事アーカイブ
【過去記事アーカイブ】Nクイーン問題 過去記事一覧
https://suzukiiichiro.github.io/search/?keyword=Nクイーン問題
【Github】エイト・クイーンのソース置き場 BashもJavaもPythonも!
https://github.com/suzukiiichiro/N-Queens
Nクイーン問題(71)Python-codonで高速化 05Python_optimize
https://suzukiiichiro.github.io/posts/2025-03-07-01-n-queens-suzuki/
Nクイーン問題(70)Python-codonで高速化 04Python_symmetry
https://suzukiiichiro.github.io/posts/2025-03-06-02-n-queens-suzuki/
Nクイーン問題(69)Python-codonで高速化 03Python_backTracking
https://suzukiiichiro.github.io/posts/2025-03-06-01-n-queens-suzuki/
Nクイーン問題(68)Python-codonで高速化 02Python_postFlag
https://suzukiiichiro.github.io/posts/2025-03-05-03-n-queens-suzuki/
Nクイーン問題(67)Python-codonで高速化 01Python_bluteForce
https://suzukiiichiro.github.io/posts/2025-03-05-02-n-queens-suzuki/
Nクイーン問題(66)Python-codonで高速化
https://suzukiiichiro.github.io/posts/2025-03-05-01-n-queens-suzuki/
Nクイーン問題(65) N25を解決!事実上の日本一に
https://suzukiiichiro.github.io/posts/2024-04-25-01-n-queens-suzuki/
Nクイーン問題(64)第七章 並列処理 キャリーチェーン NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-05-n-queens-suzuki/
Nクイーン問題(63)第七章 並列処理 キャリーチェーン NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-05-n-queens-suzuki/
Nクイーン問題(62)第七章 並列処理 対称解除法 ビットボード NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-04-n-queens-suzuki/
Nクイーン問題(61)第七章 並列処理 対称解除法 ノードレイヤー NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-03-n-queens-suzuki/
Nクイーン問題(60)第七章 並列処理 ミラー NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-02-n-queens-suzuki/
Nクイーン問題(59)第七章 並列処理 ビットマップ NVIDIA CUDA編
https://suzukiiichiro.github.io/posts/2023-08-01-01-n-queens-suzuki/
Nクイーン問題(58)第六章 並列処理 pthread C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-09-n-queens-suzuki/
Nクイーン問題(57)第八章 キャリーチェーン C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-08-n-queens-suzuki/
Nクイーン問題(56)第八章 ミラー C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-06-n-queens-suzuki/
Nクイーン問題(55)第八章 ビットマップ C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-05-n-queens-suzuki/
Nクイーン問題(54)第八章 ビットマップ C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-04-n-queens-suzuki/
Nクイーン問題(53)第八章 配置フラグ C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-03-n-queens-suzuki/
Nクイーン問題(52)第八章 バックトラック C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-02-n-queens-suzuki/
Nクイーン問題(51)第八章 ブルートフォース C言語編
https://suzukiiichiro.github.io/posts/2023-06-28-01-n-queens-suzuki/
Nクイーン問題(50)第七章 マルチプロセス Python編
https://suzukiiichiro.github.io/posts/2023-06-21-04-n-queens-suzuki/
Nクイーン問題(49)第七章 マルチスレッド Python編
https://suzukiiichiro.github.io/posts/2023-06-21-03-n-queens-suzuki/
Nクイーン問題(48)第七章 シングルスレッド Python編
https://suzukiiichiro.github.io/posts/2023-06-21-02-n-queens-suzuki/
Nクイーン問題(47)第七章 クラス Python編
https://suzukiiichiro.github.io/posts/2023-06-21-01-n-queens-suzuki/
Nクイーン問題(46)第七章 ステップNの実装 Python編
https://suzukiiichiro.github.io/posts/2023-06-16-02-n-queens-suzuki/
Nクイーン問題(45)第七章 キャリーチェーン Python編
https://suzukiiichiro.github.io/posts/2023-06-16-01-n-queens-suzuki/
Nクイーン問題(44)第七章 対象解除法 Python編
https://suzukiiichiro.github.io/posts/2023-06-14-02-n-queens-suzuki/
Nクイーン問題(43)第七章 ミラー Python編
https://suzukiiichiro.github.io/posts/2023-06-14-01-n-queens-suzuki/
Nクイーン問題(42)第七章 ビットマップ Python編
https://suzukiiichiro.github.io/posts/2023-06-13-05-n-queens-suzuki/
Nクイーン問題(41)第七章 配置フラグ Python編
https://suzukiiichiro.github.io/posts/2023-06-13-04-n-queens-suzuki/
Nクイーン問題(40)第七章 バックトラック Python編
https://suzukiiichiro.github.io/posts/2023-06-13-03-n-queens-suzuki/
Nクイーン問題(39)第七章 バックトラック準備編 Python編
https://suzukiiichiro.github.io/posts/2023-06-13-02-n-queens-suzuki/
Nクイーン問題(38)第七章 ブルートフォース Python編
https://suzukiiichiro.github.io/posts/2023-06-13-01-n-queens-suzuki/
Nクイーン問題(37)第六章 C言語移植 その17 pthread並列処理完成
https://suzukiiichiro.github.io/posts/2023-05-30-17-n-queens-suzuki/
Nクイーン問題(36)第六章 C言語移植 その16 pthreadの実装
https://suzukiiichiro.github.io/posts/2023-05-30-16-n-queens-suzuki/
Nクイーン問題(35)第六章 C言語移植 その15 pthread実装直前版完成
https://suzukiiichiro.github.io/posts/2023-05-30-15-n-queens-suzuki/
Nクイーン問題(34)第六章 C言語移植 その14
https://suzukiiichiro.github.io/posts/2023-05-30-14-n-queens-suzuki/
Nクイーン問題(33)第六章 C言語移植 その13
https://suzukiiichiro.github.io/posts/2023-05-30-13-n-queens-suzuki/
Nクイーン問題(32)第六章 C言語移植 その12
https://suzukiiichiro.github.io/posts/2023-05-30-12-n-queens-suzuki/
Nクイーン問題(31)第六章 C言語移植 その11
https://suzukiiichiro.github.io/posts/2023-05-30-11-n-queens-suzuki/
Nクイーン問題(30)第六章 C言語移植 その10
https://suzukiiichiro.github.io/posts/2023-05-30-10-n-queens-suzuki/
Nクイーン問題(29)第六章 C言語移植 その9
https://suzukiiichiro.github.io/posts/2023-05-30-09-n-queens-suzuki/
Nクイーン問題(28)第六章 C言語移植 その8
https://suzukiiichiro.github.io/posts/2023-05-30-08-n-queens-suzuki/
Nクイーン問題(27)第六章 C言語移植 その7
https://suzukiiichiro.github.io/posts/2023-05-30-07-n-queens-suzuki/
Nクイーン問題(26)第六章 C言語移植 その6
https://suzukiiichiro.github.io/posts/2023-05-30-06-n-queens-suzuki/
Nクイーン問題(25)第六章 C言語移植 その5
https://suzukiiichiro.github.io/posts/2023-05-30-05-n-queens-suzuki/
Nクイーン問題(24)第六章 C言語移植 その4
https://suzukiiichiro.github.io/posts/2023-05-30-04-n-queens-suzuki/
Nクイーン問題(23)第六章 C言語移植 その3
https://suzukiiichiro.github.io/posts/2023-05-30-03-n-queens-suzuki/
Nクイーン問題(22)第六章 C言語移植 その2
https://suzukiiichiro.github.io/posts/2023-05-30-02-n-queens-suzuki/
Nクイーン問題(21)第六章 C言語移植 その1
N-Queens問://suzukiiichiro.github.io/posts/2023-05-30-01-n-queens-suzuki/
Nクイーン問題(20)第五章 並列処理
https://suzukiiichiro.github.io/posts/2023-05-23-02-n-queens-suzuki/
Nクイーン問題(19)第五章 キャリーチェーン
https://suzukiiichiro.github.io/posts/2023-05-23-01-n-queens-suzuki/
Nクイーン問題(18)第四章 エイト・クイーンノスタルジー
https://suzukiiichiro.github.io/posts/2023-04-25-01-n-queens-suzuki/
Nクイーン問題(17)第四章 偉人のソースを読む「N24を発見 Jeff Somers」
https://suzukiiichiro.github.io/posts/2023-04-21-01-n-queens-suzuki/
Nクイーン問題(16)第三章 対象解除法 ソース解説
https://suzukiiichiro.github.io/posts/2023-04-18-01-n-queens-suzuki/
Nクイーン問題(15)第三章 対象解除法 ロジック解説
https://suzukiiichiro.github.io/posts/2023-04-13-02-nqueens-suzuki/
Nクイーン問題(14)第三章 ミラー
https://suzukiiichiro.github.io/posts/2023-04-13-01-nqueens-suzuki/
Nクイーン問題(13)第三章 ビットマップ
https://suzukiiichiro.github.io/posts/2023-04-05-01-nqueens-suzuki/
Nクイーン問題(12)第二章 まとめ
https://suzukiiichiro.github.io/posts/2023-03-17-02-n-queens-suzuki/
Nクイーン問題(11)第二章 配置フラグの再帰・非再帰
https://suzukiiichiro.github.io/posts/2023-03-17-01-n-queens-suzuki/
Nクイーン問題(10)第二章 バックトラックの再帰・非再帰
https://suzukiiichiro.github.io/posts/2023-03-16-01-n-queens-suzuki/
Nクイーン問題(9)第二章 ブルートフォースの再帰・非再帰
https://suzukiiichiro.github.io/posts/2023-03-14-01-n-queens-suzuki/
Nクイーン問題(8)第一章 まとめ
https://suzukiiichiro.github.io/posts/2023-03-09-01-n-queens-suzuki/
Nクイーン問題(7)第一章 ブルートフォース再び
https://suzukiiichiro.github.io/posts/2023-03-08-01-n-queens-suzuki/
Nクイーン問題(6)第一章 配置フラグ
https://suzukiiichiro.github.io/posts/2023-03-07-01-n-queens-suzuki/
Nクイーン問題(5)第一章 進捗表示テーブルの作成
https://suzukiiichiro.github.io/posts/2023-03-06-01-n-queens-suzuki/
Nクイーン問題(4)第一章 バックトラック
https://suzukiiichiro.github.io/posts/2023-02-21-01-n-queens-suzuki/
Nクイーン問題(3)第一章 バックトラック準備編
https://suzukiiichiro.github.io/posts/2023-02-14-03-n-queens-suzuki/
Nクイーン問題(2)第一章 ブルートフォース
https://suzukiiichiro.github.io/posts/2023-02-14-02-n-queens-suzuki/
Nクイーン問題(1)第一章 エイトクイーンについて
https://suzukiiichiro.github.io/posts/2023-02-14-01-n-queens-suzuki/