ソースコード
今回の連載 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/
ThreadPool スレッドプール
まず、はじめに PythonのThreadPool/ProcessPool/concurrent.futures版ThreadPool/concurrent.futures版ProcessPoolはcodonでは動きません!
その上で、仕方がないので Python/pypyで実装します。(まぁそれでも十分に高速化できます)
pythonの並列処理には大きく2つあります。
ThreadPool スレッドプール
ProcessPool プロセスプール
用途に合わせて使えばよいわけです。
ThreadPool 複数のスレッドを並列処理したい場合
ProcessPool 複数のプロセスを並列処理したい場合
エイトクイーンの場合は ProcessPoolのほうが若干高速でした。
マルチスレッド・マルチプロセスとも言われます。
solve()
concurrent.futures版 のマルチスレッドとマルチプロセス
ThreadPoolとProcessPoolの4つを簡単に着替えて実行できるように実装してあります。
resultsに何を代入するかを切り替えるロジックになっています。
concurrent.futures版 のマルチスレッド
def solve(self,size:int)->list:
with concurrent.futures.ThreadPoolExecutor() as executor:
params=[(thr_index,size) for thr_index in range(size) ]
#
# concurrent.futuresマルチスレッド版
# 15: 2279184 285053 0:00:05.440
results=executor.map(self.nqueen_threadPool,params)
#
# concurrent.futuresマルチプロセス版
# 15: 2279184 285053 0:00:05.526
# results=executor.map(self.nqueen_processPool,params)
#
#
pool = ThreadPool(size)
params=[(thr_index,size) for thr_index in range(size) ]
# マルチスレッド版
# 15: 2279184 285053 0:00:03.553
# results:list[int]=list(pool.map(self.nqueen_threadPool,params))
#
# マルチプロセス版
# 15: 2279184 285053 0:00:02.378
# results:list[int]=list(pool.map(self.nqueen_processPool,params))
#
#
concurrent.futures版 のマルチプロセス
def solve(self,size:int)->list:
with concurrent.futures.ThreadPoolExecutor() as executor:
params=[(thr_index,size) for thr_index in range(size) ]
#
# concurrent.futuresマルチスレッド版
# 15: 2279184 285053 0:00:05.440
# results=executor.map(self.nqueen_threadPool,params)
#
# concurrent.futuresマルチプロセス版
# 15: 2279184 285053 0:00:05.526
results=executor.map(self.nqueen_processPool,params)
#
#
pool = ThreadPool(size)
params=[(thr_index,size) for thr_index in range(size) ]
# マルチスレッド版
# 15: 2279184 285053 0:00:03.553
# results:list[int]=list(pool.map(self.nqueen_threadPool,params))
#
# マルチプロセス版
# 15: 2279184 285053 0:00:02.378
# results:list[int]=list(pool.map(self.nqueen_processPool,params))
#
#
ThreadPool版 のマルチスレッド
def solve(self,size:int)->list:
with concurrent.futures.ThreadPoolExecutor() as executor:
params=[(thr_index,size) for thr_index in range(size) ]
#
# concurrent.futuresマルチスレッド版
# 15: 2279184 285053 0:00:05.440
# results=executor.map(self.nqueen_threadPool,params)
#
# concurrent.futuresマルチプロセス版
# 15: 2279184 285053 0:00:05.526
# results=executor.map(self.nqueen_processPool,params)
#
#
pool = ThreadPool(size)
params=[(thr_index,size) for thr_index in range(size) ]
# マルチスレッド版
# 15: 2279184 285053 0:00:03.553
results:list[int]=list(pool.map(self.nqueen_threadPool,params))
#
# マルチプロセス版
# 15: 2279184 285053 0:00:02.378
# results:list[int]=list(pool.map(self.nqueen_processPool,params))
#
#
ProcessPool版 のマルチプロセス
def solve(self,size:int)->list:
with concurrent.futures.ThreadPoolExecutor() as executor:
params=[(thr_index,size) for thr_index in range(size) ]
#
# concurrent.futuresマルチスレッド版
# 15: 2279184 285053 0:00:05.440
# results=executor.map(self.nqueen_threadPool,params)
#
# concurrent.futuresマルチプロセス版
# 15: 2279184 285053 0:00:05.526
# results=executor.map(self.nqueen_processPool,params)
#
#
pool = ThreadPool(size)
params=[(thr_index,size) for thr_index in range(size) ]
# マルチスレッド版
# 15: 2279184 285053 0:00:03.553
# results:list[int]=list(pool.map(self.nqueen_threadPool,params))
#
# マルチプロセス版
# 15: 2279184 285053 0:00:02.378
results:list[int]=list(pool.map(self.nqueen_processPool,params))
#
#
nqueen_threadPool()もnqueen_processPool()も実装済みです。
並列処理後に集計を集約する部分が良く書けています。
zip()された集計結果群を並列処理の数だけ分解してsum()で合計を出し、int型のtotal_counts
に代入しています。
def solve(self,size:int)->list:
with concurrent.futures.ThreadPoolExecutor() as executor:
:
:
:
# スレッドごとの結果を集計
total_counts:int=[sum(x) for x in zip(*results)]
total:int=self.gettotal(total_counts)
unique:int=self.getunique(total_counts)
return [total,unique]
ソースコード
# -*- coding: utf-8 -*-
import subprocess
from datetime import datetime
#
# pypyを使うときは以下を活かしてcodon部分をコメントアウト
# pypy では ThreadPool/ProcessPoolが動きます
#
import pypyjit
pypyjit.set_param('max_unroll_recursion=-1')
from threading import Thread
from multiprocessing import Pool as ThreadPool
import concurrent
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import ProcessPoolExecutor
#
#
# codonを使うときは以下を活かして上記をコメントアウト
# ThreadPool/ProcessPoolはcodonでは動きません
#
# from python import Pool as ThreadPool
# from python import Thread
# from python import threading
# from python import multiprocessing
# from python import concurrent
# from python import ThreadPoolExecutor
# from python import ProcessPoolExecutor
class NQueens09():
def __init__(self):
pass
def getunique(self,counts:list)->int:
count2:int
count4:int
count8:int
count2,count4,count8=counts
return count2+count4+count8
def gettotal(self,counts:list)->int:
count2:int
count4:int
count8:int
count2,count4,count8=counts
return count2*2+count4*4+count8*8
def symmetryops(self,size:int,aboard:list,topbit:int,endbit:int,sidemask:int,lastmask:int,bound1:int,bound2:int)->list:
count2:int
count4:int
count8:int
count2=count4=count8=0
own:int
ptn:int
you:int
bit:int
if aboard[bound2]==1:
own,ptn=1,2
for own in range(1,size):
bit=1
you=size-1
while aboard[you]!=ptn and aboard[own]>=bit:
bit<<=1
you-=1
if aboard[own]>bit:
return [count2,count4,count8]
if aboard[own]<bit:
break
ptn<<=1
else:
count2+=1
return [count2,count4,count8]
if aboard[size-1]==endbit:
own,you=1,size-2
for own in range(1,size):
bit,ptn=1,topbit
while aboard[you]!=ptn and aboard[own]>=bit:
bit<<=1
ptn>>=1
if aboard[own]>bit:
return [count2,count4,count8]
if aboard[own]<bit:
break
you-=1
else:
count4+=1
return [count2,count4,count8]
if aboard[bound1]==topbit:
ptn=topbit>>1
for own in range(1,size):
bit=1
you=0
while aboard[you]!=ptn and aboard[own]>=bit:
bit<<=1
you+=1
if aboard[own]>bit:
return [count2,count4,count8]
if aboard[own]<bit:
break
ptn>>=1
count8+=1
return [count2,count4,count8]
def backTrack2(self,size:int,row:int,left:int,down:int,right:int,aboard:list,topbit:int,endbit:int,sidemask:int,lastmask:int,bound1:int,bound2:int)->list:
count2:int
count4:int
count8:int
count2=count4=count8=0
bit:int
mask:int=(1<<size)-1
bitmap:int=mask&~(left|down|right)
# 最下行の場合、最適化のための条件チェック
if row==size-1:
if bitmap and (bitmap&lastmask)==0:
aboard[row]=bitmap
count2,count4,count8=self.symmetryops(size,aboard,topbit,endbit,sidemask,lastmask,bound1,bound2)
return [count2,count4,count8]
# 上部の行であればサイドマスク適用
if row<bound1:
bitmap&=~sidemask
elif row==bound2:
# `bound2` 行の場合、
# サイドマスクとの一致を確認し不要な分岐を排除
if (down&sidemask)==0:
return [count2,count4,count8]
elif (down&sidemask)!=sidemask:
bitmap&=sidemask
c2:int
c4:int
c8:int
while bitmap:
bit=bitmap&-bitmap # 最右ビットを抽出
bitmap^=bit # 最右ビットを消去
aboard[row]=bit
c2,c4,c8=self.backTrack2(size,row+1,(left|bit)<<1,down|bit,(right|bit) >> 1,aboard,topbit,endbit,sidemask,lastmask,bound1,bound2)
count2+=c2
count4+=c4
count8+=c8
return [count2,count4,count8]
def backTrack1(self,size:int,row:int,left:int,down:int,right:int,aboard:list,topbit:int,endbit:int,sidemask:int,lastmask:int,bound1:int,bound2:int)->list:
count2:int=0
count4:int=0
count8:int=0
c2:int
c4:int
c8:int
bit:int
mask:int=(1<<size)-1
bitmap:int=mask & ~(left|down|right)
if row==size-1: # 最下行に達した場合の処理
if bitmap:
aboard[row]=bitmap
count8+=1
return [count2,count4,count8]
if row<bound1: # 上部の行であればマスク適用
bitmap &= ~2
while bitmap:
bit=bitmap&-bitmap # 最右ビットを抽出
bitmap^=bit # 最右ビットを消去
aboard[row]=bit
c2,c4,c8=self.backTrack1(size,row+1,(left|bit)<<1,down|bit,(right|bit) >> 1,aboard,topbit,endbit,sidemask,lastmask,bound1,bound2)
count2+=c2
count4+=c4
count8+=c8
return [count2,count4,count8]
def nqueen_processPool(self,value:list)->list:
thr_index,size=value
sizeE=size-1
aboard:list[int]=[0 for i in range(size)]
# aboard:list[int]
# for i in range(size):
# aboard[i]=0
# aboard=[[0]*size*2]*size
# aboard=[[i for i in range(2*size-1)]for j in range(size)]
bit:int
topbit:int
endbit:int
sidemask:int
lastmask:int
bound1:int
bound2:int
count2:int
count4:int
count8:int
c2:int
c4:int
c8:int
bit=topbit=endbit=sidemask=lastmask=bound1=bound2=count2=count4=count8=0
aboard[0]=1
topbit=1<<sizeE
bound1=size-thr_index-1
if 1<bound1<sizeE:
aboard[1]=bit=1<<bound1
c2,c4,c8=self.backTrack1(size,2,(2|bit)<<1,(1|bit),(bit>>1),aboard,topbit,endbit,sidemask,lastmask,bound1,bound2)
count2+=c2
count4+=c4
count8+=c8
endbit=topbit>>1
sidemask=lastmask=topbit|1
bound2=thr_index
if 0<bound1<bound2<sizeE:
aboard[0]=bit=(1<<bound1)
for i in range(1,bound1):
lastmask|=lastmask>>1|lastmask<<1
endbit>>=1
c2,c4,c8=self.backTrack2(size,1,bit<<1,bit,bit>>1,aboard,topbit,endbit,sidemask,lastmask,bound1,bound2)
count2+=c2
count4+=c4
count8+=c8
return count2,count4,count8
def nqueen_threadPool(self,value:list)->list:
thr_index,size=value
sizeE:int=size-1
aboard:list[int]=[0 for i in range(size)]
# aboard:list[int]
# aboard=[[0]*size*2]*size
# aboard:list[int]=[[0]*size*2]*size
# for i in range(size):
# aboard[i]=0
# aboard=[[i for i in range(2*size-1)]for j in range(size)]
# aboard:list[int]
# for i in range(size):
# aboard.insert(i,0)
bit:int
topbit:int
endbit:int
sidemask:int
lastmask:int
bound1:int
bound2:int
count2:int
count4:int
count8:int
c2:int
c4:int
c8:int
bit=topbit=endbit=sidemask=lastmask=bound1=bound2=count2=count4=count8=0
aboard[0]=1
topbit=1<<sizeE
bound1=size-thr_index-1
if 1<bound1<sizeE:
aboard[1]=bit=1<<bound1
c2,c4,c8=self.backTrack1(size,2,(2|bit)<<1,(1|bit),(bit>>1),aboard,topbit,endbit,sidemask,lastmask,bound1,bound2)
count2+=c2
count4+=c4
count8+=c8
endbit=topbit>>1
sidemask=lastmask=topbit|1
bound2=thr_index
if 0<bound1<bound2<sizeE:
aboard[0]=bit=(1<<bound1)
for i in range(1,bound1):
lastmask|=lastmask>>1|lastmask<<1
endbit>>=1
c2,c4,c8=self.backTrack2(size,1,bit<<1,bit,bit>>1,aboard,topbit,endbit,sidemask,lastmask,bound1,bound2)
count2+=c2
count4+=c4
count8+=c8
return [count2,count4,count8]
def solve(self,size:int)->list:
with concurrent.futures.ThreadPoolExecutor() as executor:
params=[(thr_index,size) for thr_index in range(size) ]
#
# concurrent.futuresマルチスレッド版
# 15: 2279184 285053 0:00:05.440
# results=executor.map(self.nqueen_threadPool,params)
#
# concurrent.futuresマルチプロセス版
# 15: 2279184 285053 0:00:05.526
# results=executor.map(self.nqueen_processPool,params)
#
#
pool = ThreadPool(size)
params=[(thr_index,size) for thr_index in range(size) ]
# マルチスレッド版
# 15: 2279184 285053 0:00:03.553
results:list[int]=list(pool.map(self.nqueen_threadPool,params))
#
# マルチプロセス版
# 15: 2279184 285053 0:00:02.378
# results:list[int]=list(pool.map(self.nqueen_processPool,params))
#
#
# スレッドごとの結果を集計
total_counts:int=[sum(x) for x in zip(*results)]
total:int=self.gettotal(total_counts)
unique:int=self.getunique(total_counts)
return [total,unique]
class NQueens09_threadPool:
def finalize(self)->None:
cmd="killall pypy" # python or pypy
p = subprocess.Popen("exec " + cmd, shell=True)
p.kill()
def main(self):
nmin:int=4
nmax:int=18
print(" N: Total Unique hh:mm:ss.ms")
for size in range(nmin, nmax):
start_time=datetime.now()
NQ=NQueens09()
total,unique=NQ.solve(size)
time_elapsed=datetime.now()-start_time
text = str(time_elapsed)[:-3]
print(f"{size:2d}:{total:13d}{unique:13d}{text:>20s}")
self.finalize()
#
# $ python <filename>
# $ pypy <fileName>
# $ codon build -release <filename>
# codon ではスレッドプールが動かなかった
# スレッドプール
# 15: 2279184 285053 0:00:04.684
if __name__ == '__main__':
NQueens09_threadPool().main()
実行結果
CentOS$ pypy 09Python_bit_symmetry_ThreadPool.py
N: Total Unique hh:mm:ss.ms
4: 2 1 0:00:00.028
5: 10 2 0:00:00.020
6: 4 1 0:00:00.024
7: 40 6 0:00:00.033
8: 92 12 0:00:00.028
9: 352 46 0:00:00.036
10: 724 92 0:00:00.065
11: 2680 341 0:00:00.086
12: 14200 1787 0:00:00.150
13: 73712 9233 0:00:00.251
14: 365596 45752 0:00:00.631
15: 2279184 285053 0:00:03.151
16: 14772512 1846955 0:00:19.591
17: 95815104 11977939 0:01:55.922
次の章では、ビット版並列処理のProcessPoolを具体的にご説明していきます。
(注意)ThreadPoolとProcessPoolはPython/Pypyで動作し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クイーン問題(75)Python-並列処理で高速化 09Python_bit_symmetry_ThreadPool
https://suzukiiichiro.github.io/posts/2025-03-10-04-n-queens-suzuki/
Nクイーン問題(74)Python-codonで高速化 08Python_bit_symmetry
https://suzukiiichiro.github.io/posts/2025-03-10-03-n-queens-suzuki/
Nクイーン問題(73)Python-codonで高速化 07Python_bit_mirror
https://suzukiiichiro.github.io/posts/2025-03-10-02-n-queens-suzuki/
Nクイーン問題(72)Python-codonで高速化 06Python_bit_backTrack
https://suzukiiichiro.github.io/posts/2025-03-10-01-n-queens-suzuki/
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/