In the first seminar assignment, your goal is to use genetic algorithms to find a path out of a maze,
represented as a vector of strings, where $\#$ characters represent walls, $.$ represent empty spaces, and
S and E represent the starting and ending points, as in a given example below:
\begin{center}
\begin{BVerbatim}
maze = c("####E######",
"##...#.####",
"#..#.#.####",
"#.##...####",
"#.##.#..S##",
"###########")
\end{BVerbatim}
\end{center}
You can move through the maze in four directions, left, right, up, and down. In the example above,
the shortest path from the starting position S to the exit E is composed of the following moves: left,
left, up, left, left, up, up, up. In your solution, this should be represented as a string ”LLULLUUU”.
Your task is to create a function that will be able to find path as short as possible out of any maze
represented in such a way
\section{Solution}
\subsection{Task 1}
I decided to write this assignment in python using the pygad library becouse I am more familiar with this programming language.
\subsubsection{Task description}
Create a function that reads the 2D representation of a maze and returns the shortest path found by
a genetic algorithm. To do this, you will need to:
\begin{itemize}
\item Read the map into a suitable format (for example, a matrix).
\item choose a suitable representation of your solutions (the path). Hint: you don’t need to use strings
when working with the genetic algorithm. You can use numeric or binary representations for the
GA function and then convert the result to a string as the final result.
\item Define the fitness function. Make sure to penalise paths through walls - those are invalid solutions
\item Run the genetic algorithm with suitable settings.
\end{itemize}
\subsubsection{Read the map into a suitable format}
I decided to read all the maps provided in the assignment into a list of lists. Each list represents a
maze and each element of the list represents a row of the maze.
\subsubsection{Choose a suitable representation of your solutions}
I decided to use a binary representation of the solution same size as an original maze. Each bit represents a move. 0 means that the agent did
not visit the cell and 1 means that the agent visited the cell. So if maze is of size N x M, the solution will be of size N x M. But there is no
such thing as N-dimensional array that GA accepts. So I reshaped the matrix into a vector of size N * M and worked with that kind of solution.
\subsubsection{Define the fitness function}
This part was the most difficult for me. I maybe overcomplicated that part but at least it yields good results.
Before runing the algorithm I have decided to construct a punish matrix, which is a matrix of the same size as the maze. Each cell in the punish matrix is
evaluated before the algorithm starts. The evaluation is based on the position of walls and valid paths. So if there is a wall in the cell, the fitness value in that cell is set to some low scalar.
If there is a valid move then the fitness value in that cell is high. So everytime the fitness function is called, the matrix product will be executed and some initiall fitness value will be computed asfollows:
But though experimentation I found that this approach was not good enough so I modified the function by adding punsihment if the agent did not start at the starting position and
if the agent did not end at the ending position. Still the results were not good enough so I decided to check if there is a valid path from the starting position to the ending position.
If there is no valid path then I would punish the agent otherwise I would give him some reward. This approach yielded better results.
But still I was not satisfied with the results so I decided to add some more punishes and rewards:
\begin{itemize}
\item Add a reward if agent finds a shorter path than the best path found so far.
\item Update weights in punish matrix so that the agent will prefer to move on best path found so far.
\item If the agent does not find any valid path until 80\% of the GA iterations then activate critical search phase. That means that the agent
will be rewarded if he finds \textbf{any} path from start to end, even if it maybe isn't the correct one. This way the weights are updated
so that it converges to the correct path.
\end{itemize}
\subsubsection{Run the genetic algorithm with suitable settings}
I used the following settings wen running the algorithm:
\begin{small}
\begin{itemize}
\item\begin{verbatim}number_of_genes = N * M \end{verbatim}(if the maze is of size N x M)
Other mazes found also found some solutions, but they were not optimal. Or they were trying to go through a wall becouse the critical section was activated. I think that the problem is that the mutation and crossover operators are not good enough.