第2章 まとめ
ここまでNクイーンをこんなにやってきました。
N-Queens問題:Nクイーン問題(12)第二章 まとめ
https://suzukiiichiro.github.io/posts/2023-03-17-02-n-queens-suzuki/
N-Queens問題:Nクイーン問題(11)第二章 配置フラグの再帰・非再帰
https://suzukiiichiro.github.io/posts/2023-03-17-01-n-queens-suzuki/
N-Queens問題:Nクイーン問題(10)第二章 バックトラックの再帰・非再帰
https://suzukiiichiro.github.io/posts/2023-03-16-01-n-queens-suzuki/
N-Queens問題:Nクイーン問題(9)第二章 ブルートフォースの再帰・非再帰
https://suzukiiichiro.github.io/posts/2023-03-14-01-n-queens-suzuki/
N-Queens問題:Nクイーン問題(8)第一章 まとめ
https://suzukiiichiro.github.io/posts/2023-03-09-01-n-queens-suzuki/
N-Queens問題:Nクイーン問題(7)第一章 ブルートフォース再び
https://suzukiiichiro.github.io/posts/2023-03-08-01-n-queens-suzuki/
N-Queens問題:Nクイーン問題(6)第一章 配置フラグ
https://suzukiiichiro.github.io/posts/2023-03-07-01-n-queens-suzuki/
N-Queens問題:Nクイーン問題(5)第一章 進捗表示テーブルの作成
https://suzukiiichiro.github.io/posts/2023-03-06-01-n-queens-suzuki/
N-Queens問題:Nクイーン問題(4)第一章 バックトラック
https://suzukiiichiro.github.io/posts/2023-02-21-01-n-queens-suzuki/
N-Queens問題:Nクイーン問題(3)第一章 バックトラック準備編
https://suzukiiichiro.github.io/posts/2023-02-14-03-n-queens-suzuki/
N-Queens問題:Nクイーン問題(2)第一章 ブルートフォース
https://suzukiiichiro.github.io/posts/2023-02-14-02-n-queens-suzuki/
N-Queens問題:Nクイーン問題(1)第一章 エイトクイーンについて
https://suzukiiichiro.github.io/posts/2023-02-14-01-n-queens-suzuki/
エイト・クイーンのソース置き場 BashもJavaもPythonも!
https://github.com/suzukiiichiro/N-Queens
ここまでで第二章は終わりとなります。
まとめとして、ブルートフォース、バックトラック、配置フラグそれぞれの「再帰」「非再帰」の処理時間、またはボートレイアウト画面の出力ができるメニューの作成を行っていきます。
実行結果はこんな感じです。ボード画面の出力もできます。
bash-3.2$ bash N-Queens.sh
エイト・クイーン メニュー
実行したい番号を選択
6) 非再帰 配置フラグ
5) 再帰 配置フラグ
4) 非再帰 バックトラック
3) 再帰 バックトラック
2) 非再帰 ブルートフォース
1) 再帰 ブルートフォース
echo 行頭の番号を入力してください;
6
ボード画面の表示は?
y) する(ブルートフォースはおすすめしない)
n) しない
echo 行頭のアルファベットを入力して下さい;
n
N: Total Unique hh:mm:ss
4: 2 0 0:00:00
5: 10 0 0:00:00
6: 4 0 0:00:00
7: 40 0 0:00:00
8: 92 0 0:00:00
9: 352 0 0:00:02
^C
bash-3.2$
プログラムソース
プログラムソースは以下のとおりです。
#!/usr/bin/bash
declare -i COUNT=0;
declare -i TOTAL=0; # カウンター
declare -i UNIQUE=0; # ユニークユーザー
declare -i DISPLAY=0; # ボード出力するか
#
#
: 'ボードレイアウトを出力';
function printRecord(){
size="$1";
echo "$TOTAL";
sEcho=" ";
for((i=0;i<size;i++)){
sEcho="${sEcho}${board[i]} ";
}
echo "$sEcho";
echo -n "+";
for((i=0;i<size;i++)){
echo -n "-";
if((i<(size-1)));then
echo -n "+";
fi
}
echo "+";
for((i=0;i<size;i++)){
echo -n "|";
for((j=0;j<size;j++)){
if((i==board[j]));then
echo -n "O";
else
echo -n " ";
fi
if((j<(size-1)));then
echo -n "|";
fi
}
echo "|";
if((i<(size-1)));then
echo -n "+";
for((j=0;j<size;j++)){
echo -n "-";
if((j<(size-1)));then
echo -n "+";
fi
}
echo "+";
fi
}
echo -n "+";
for((i=0;i<size;i++)){
echo -n "-";
if((i<(size-1)));then
echo -n "+";
fi
}
echo "+";
echo "";
}
#
: 'バックトラック版効き筋をチェック';
function check_backTracking(){
local -i row="$1";
local -i flag=1;
for ((i=0;i<row;++i)){
if (( board[i]>=board[row] ));then
val=$(( board[i]-board[row] ));
else
val=$(( board[row]-board[i] ));
fi
if (( board[i]==board[row] || val==(row-i) ));then
flag=0;
fi
}
[[ $flag -eq 0 ]]
return $?;
}
#
: 'ブルートフォース版効き筋をチェック';
function check_bluteForce(){
local -i size="$1";
local -i flag=1;
for ((r=1;r<size;++r)){
for ((i=0;i<r;++i)){
#echo `$(($1-$2)) | sed -e "s/^-//g"`;
if (( board[i]>=board[r] ));then
val=$(( board[i]-board[r] ));
else
val=$(( board[r]-board[i] ));
fi
if (( board[i]==board[r] || val==(r-i) ));then
flag=0;
fi
}
}
[[ $flag -eq 0 ]]
return $?;
}
#
: '非再帰版配置フラグ(right/down/left flag)';
function rdlFlag_NR(){
local -i row="$1"
local -i size="$2";
local -i matched=0;
for ((i=0;i<size;i++)){ board[$i]=-1; }
while ((row>-1));do
matched=0;
for ((col=board[row]+1;col<size;col++)){
if (( !down[col]
&& !right[col-row+size-1]
&& !left[col+row] ));then
dix=$col;
rix=$((row-col+(size-1)));
lix=$((row+col));
if ((board[row]!=-1));then
down[${board[$row]}]=0;
right[${board[$row]}-$row+($size-1)]=0;
left[${board[$row]}+$row]=0;
fi
board[$row]=$col; # Qを配置
down[$col]=1;
right[$col-$row+($size-1)]=1;
left[$col+$row]=1; # 効き筋とする
matched=1; # 配置した
break;
fi
}
if ((matched));then # 配置済み
((row++)); #次のrowへ
if ((row==size));then
((TOTAL++));
printRecord "$size";# 出力
((row--));
fi
else
if ((board[row]!=-1));then
down[${board[$row]}]=0;
right[${board[$row]}-$row+($size-1)]=0;
left[${board[$row]}+$row]=0;
board[$row]=-1;
fi
((row--)); # バックトラック
fi
done
}
#
#
: '再帰版配置フラグ';
function rdlFlag_R(){
local -i row="$1";
local -i size="$2";
local -i col=0; # 再帰に必要
if (( row==size ));then
((TOTAL++));
if (( DISPLAY==1 ));then
printRecord "$size";# 出力
fi
else
for(( col=0;col<size;col++ )){
board[$row]="$col";
if (( down[col]==0
&& right[row-col+size-1]==0
&& left[row+col]==0));then
down[$col]=1;
right[$row-$col+($size-1)]=1;
left[$row+$col]=1;
rdlFlag_R "$((row+1))" "$size" ;
down[$col]=0;
right[$row-$col+($size-1)]=0;
left[$row+$col]=0;
fi
}
fi
}
#
: '非再帰版バックトラック';
function backTracking_NR(){
local -i row="$1";
local -i size="$2";
for ((i=0;i<size;i++)){ board[$i]=-1; }
while ((row>-1));do
local -i matched=0;
local -i col=0;
for((col=board[row]+1;col<size;col++)){
board[$row]=$col;
check_backTracking "$row"; # 効きをチェック
if (($?==1));then # 直前のreturnを利用
matched=1;
break;
fi
}
if ((matched));then
((row++));
if ((row==size));then # 最下部まで到達
((row--));
((TOTAL++));
if (( DISPLAY==1 ));then
printRecord "$size";# 出力
fi
fi
else
if ((board[row]!=-1));then
board[$row]=-1;
fi
((row--));
fi
done
}
#
: '再帰版バックトラック';
function backTracking_R(){
local -i row="$1";
local -i size="$2";
local -i col=0;
if ((row==size));then
((TOTAL++));
if (( DISPLAY==1 ));then
printRecord "$size";# 出力
fi
else
for(( col=0;col<size;col++ )){
board["$row"]="$col";
check_backTracking "$row";
if (($?==1));then
backTracking_R $((row+1)) $size ;
fi
}
fi
}
#
: '非再帰版ブルートフォース';
function bluteForce_NR(){
local -i row="$1";
local -i size="$2";
for ((i=0;i<size;i++)){ board[$i]=-1; }
while ((row>-1));do
local -i matched=0;
local -i col=0;
for((col=board[row]+1;col<size;col++)){
board[$row]=$col;
matched=1;
break;
}
if ((matched));then
((row++));
if ((row==size));then # 最下部まで到達
((row--));
check_bluteForce "$size"; # 効きをチェック
if (($?==1));then # 直前のreturnを利用
((TOTAL++));
if (( DISPLAY==1 ));then
printRecord "$size";# 出力
fi
fi
fi
else
if ((board[row]!=-1));then
board[$row]=-1;
fi
((row--));
fi
done
}
: '再帰版ブルートフォース';
function bluteForce_R(){
local -i row="$1";
local -i size="$2";
local -i col=;
if ((row==size));then
check_bluteForce "$size";
if (( $?==1 ));then
((TOTAL++));
if (( DISPLAY==1 ));then
printRecord "$size";# 出力
fi
fi
else
#for(( col=0;col<(size-row);col++ )){
for(( col=0;col<size;col++ )){
board["$row"]="$col";
bluteForce_R $((row+1)) $size ;
}
fi
}
#
function NQ(){
local selectName="$1";
local -i max=15;
local -i min=4;
local -i N="$min";
local startTime=0;
local endTime=0;
local hh=mm=ss=0;
echo " N: Total Unique hh:mm:ss" ;
for((N=min;N<=max;N++)){
TOTAL=0;
UNIQUE=0;
startTime=$(date +%s);# 計測開始時間
"$selectName" 0 "$N";
endTime=$(date +%s); # 計測終了時間
ss=$((endTime-startTime));# hh:mm:ss 形式に変換
hh=$((ss/3600));
ss=$((ss%3600));
mm=$((ss/60));
ss=$((ss%60));
printf "%2d:%13d%13d%10d:%.2d:%.2d\n" $N $TOTAL $UNIQUE $hh $mm $ss ;
}
}
while :
do
read -n1 -p "
エイト・クイーン メニュー
実行したい番号を選択
6) 非再帰 配置フラグ
5) 再帰 配置フラグ
4) 非再帰 バックトラック
3) 再帰 バックトラック
2) 非再帰 ブルートフォース
1) 再帰 ブルートフォース
echo "行頭の番号を入力してください";
" selectNo;
echo
case "$selectNo" in
6)
while :
do
read -n1 -p "
ボード画面の表示は?
y) する(ブルートフォースはおすすめしない)
n) しない
echo "行頭のアルファベットを入力して下さい";
" select;
echo;
case "$select" in
y|Y) DISPLAY=1; break; ;;
n|N) DISPLAY=0; break; ;;
esac
done
NQ rdlFlag_NR
break;
;;
5)
while :
do
read -n1 -p "
ボード画面の表示は?
y) する(ブルートフォースはおすすめしない)
n) しない
echo "行頭のアルファベットを入力して下さい";
" select;
echo;
case "$select" in
y|Y) DISPLAY=1; break; ;;
n|N) DISPLAY=0; break; ;;
esac
done
NQ rdlFlag_R;
break;
;;
4)
while :
do
read -n1 -p "
ボード画面の表示は?
y) する(ブルートフォースはおすすめしない)
n) しない
echo "行頭のアルファベットを入力して下さい";
" select;
echo;
case "$select" in
y|Y) DISPLAY=1; break; ;;
n|N) DISPLAY=0; break; ;;
esac
done
NQ backTracking_NR;
break;
;;
3)
while :
do
read -n1 -p "
ボード画面の表示は?
y) する(ブルートフォースはおすすめしない)
n) しない
echo "行頭のアルファベットを入力して下さい";
" select;
echo;
case "$select" in
y|Y) DISPLAY=1; break; ;;
n|N) DISPLAY=0; break; ;;
esac
done
NQ backTracking_R;
break;
;;
2)
while :
do
read -n1 -p "
ボード画面の表示は?
y) する(ブルートフォースはおすすめしない)
n) しない
echo "行頭のアルファベットを入力して下さい";
" select;
echo;
case "$select" in
y|Y) DISPLAY=1; break; ;;
n|N) DISPLAY=0; break; ;;
esac
done
NQ bluteForce_NR;
break;
;;
1)
while :
do
read -n1 -p "
ボード画面の表示は?
y) する(ブルートフォースはおすすめしない)
n) しない
echo "行頭のアルファベットを入力して下さい";
" select;
echo;
case "$select" in
y|Y) DISPLAY=1; break; ;;
n|N) DISPLAY=0; break; ;;
esac
done
NQ bluteForce_R;
break;
;;
*)
;;
esac
done
exit;
実行結果
bash-3.2$ bash N-Queens.sh
エイト・クイーン メニュー
実行したい番号を選択
6) 非再帰 配置フラグ
5) 再帰 配置フラグ
4) 非再帰 バックトラック
3) 再帰 バックトラック
2) 非再帰 ブルートフォース
1) 再帰 ブルートフォース
echo 行頭の番号を入力してください;
6
ボード画面の表示は?
y) する(ブルートフォースはおすすめしない)
n) しない
echo 行頭のアルファベットを入力して下さい;
n
N: Total Unique hh:mm:ss
4: 2 0 0:00:00
5: 10 0 0:00:00
6: 4 0 0:00:00
7: 40 0 0:00:00
8: 92 0 0:00:00
9: 352 0 0:00:02
^C
bash-3.2$
やっと第二章が終わったわけですが、まだまだNクイーンは高速になります。
ここまでで五合目といったところです。
ブルートフォースはあんなに遅かったのに、配置フラグでは目に見えて高速になりました。
第三章をどこから始めるか。今、そこを悩んでいます。
お楽しみに。
参考リンク
以下の詳細説明を参考にしてください。
【参考リンク】Nクイーン問題 過去記事一覧
【Github】エイト・クイーンのソース置き場 BashもJavaもPythonも!
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/