Add FAIRK1 alpha-beta cuts
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 47 KiB |
BIN
src/fundamentals-of-ai-and-kr/module1/img/alphabeta_example1.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
src/fundamentals-of-ai-and-kr/module1/img/alphabeta_example2.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
src/fundamentals-of-ai-and-kr/module1/img/alphabeta_example3.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
src/fundamentals-of-ai-and-kr/module1/img/alphabeta_example4.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
src/fundamentals-of-ai-and-kr/module1/img/alphabeta_example5.png
Normal file
|
After Width: | Height: | Size: 81 KiB |
@ -72,17 +72,75 @@ an iteration of the minimax algorithm can be described as follows:
|
|||||||
\begin{algorithm}
|
\begin{algorithm}
|
||||||
\caption{Minimax algorithm}
|
\caption{Minimax algorithm}
|
||||||
\begin{lstlisting}[mathescape=true]
|
\begin{lstlisting}[mathescape=true]
|
||||||
def minimax(node, who_is_next):
|
def minimax(node, max_depth, who_is_next):
|
||||||
if isLeaf(node):
|
if node.isLeaf() or max_depth == 0:
|
||||||
eval = evaluate(node)
|
eval = evaluate(node)
|
||||||
elif who_is_next == ME:
|
elif who_is_next == ME:
|
||||||
eval = $-\infty$
|
eval = -$\infty$
|
||||||
for c in node.children: # Expansion if needed
|
for c in node.children:
|
||||||
eval = max(eval, minimax(c, OPPONENT))
|
eval = max(eval, minimax(c, max_depth-1, OPPONENT))
|
||||||
elif who_is_next == OPPONENT:
|
elif who_is_next == OPPONENT:
|
||||||
eval = $+\infty$
|
eval = +$\infty$
|
||||||
for c in node.children: # Expansion if needed
|
for c in node.children:
|
||||||
eval = min(eval, minimax(c, ME))
|
eval = min(eval, minimax(c, max_depth-1, ME))
|
||||||
return eval
|
return eval
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
\end{algorithm}
|
\end{algorithm}
|
||||||
|
|
||||||
|
|
||||||
|
\section{Alpha-beta cuts}
|
||||||
|
\marginnote{Alpha-beta cuts}
|
||||||
|
Alpha-beta cuts (pruning) allows to prune subtrees whose state will never be selected (when playing optimally).
|
||||||
|
$\alpha$ represents the best choice found for \textsc{Max}.
|
||||||
|
$\beta$ represents the best choice found for \textsc{Min}.
|
||||||
|
|
||||||
|
The best case for alpha-beta cuts is when the best nodes are evaluated first.
|
||||||
|
In this scenario, the theoretical number of nodes to explore is decreased to $O(b^{d/2})$.
|
||||||
|
In practice, the reduction is of order $O(\sqrt{b^d})$.
|
||||||
|
In the average case of a random distribution, the reduction is of order $O(b^{3d/4})$.
|
||||||
|
|
||||||
|
\begin{algorithm}
|
||||||
|
\caption{Minimax with alpha-beta cuts}
|
||||||
|
\begin{lstlisting}[mathescape=true]
|
||||||
|
def alphabeta(node, max_depth, who_is_next, $\alpha$=-$\infty$, $\beta$=+$\infty$):
|
||||||
|
if node.isLeaf() or max_depth == 0:
|
||||||
|
eval = evaluate(node)
|
||||||
|
elif who_is_next == ME:
|
||||||
|
eval = -$\infty$
|
||||||
|
for c in node.children:
|
||||||
|
eval = max(eval, alphabeta(c, max_depth-1, OPPONENT, $\alpha$, $\beta$))
|
||||||
|
$\alpha$ = max(eval, $\alpha$)
|
||||||
|
if eval >= $\beta$: break # cutoff
|
||||||
|
elif who_is_next == OPPONENT:
|
||||||
|
eval = +$\infty$
|
||||||
|
for c in node.children:
|
||||||
|
eval = min(eval, alphabeta(c, max_depth-1, ME, $\alpha$, $\beta$))
|
||||||
|
$\beta$ = min(eval, $\beta$)
|
||||||
|
if eval <= $\alpha$: break # cutoff
|
||||||
|
return eval
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{algorithm}
|
||||||
|
|
||||||
|
\begin{figure}[h]
|
||||||
|
\begin{subfigure}{.3\textwidth}
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=\linewidth]{img/alphabeta_algo_example1.png}
|
||||||
|
\end{subfigure}
|
||||||
|
\begin{subfigure}{.3\textwidth}
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=\linewidth]{img/alphabeta_algo_example2.png}
|
||||||
|
\end{subfigure}
|
||||||
|
\begin{subfigure}{.4\textwidth}
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=\linewidth]{img/alphabeta_algo_example3.png}
|
||||||
|
\end{subfigure}
|
||||||
|
\begin{subfigure}{.4\textwidth}
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=\linewidth]{img/alphabeta_algo_example4.png}
|
||||||
|
\end{subfigure}
|
||||||
|
\begin{subfigure}{.4\textwidth}
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=\linewidth]{img/alphabeta_algo_example5.png}
|
||||||
|
\end{subfigure}
|
||||||
|
\caption{Algorithmic (left) and intuitive (right) application of alpha-beta cuts}
|
||||||
|
\end{figure}
|
||||||