\documentclass{article} \date{2022-09-29} %\usepackage{amsmath} %\usepackage{amssymb} \usepackage{fancyhdr} \usepackage[hmargin=1in,vmargin=1in]{geometry} \pagestyle{fancy} \lhead{Emi Simpson} \chead{Introduction to AI - Lab 1 - Summer Orienteering} \rhead{\thepage} \fancyfoot{} \newcommand{\f}[1]{\textnormal{#1}} \newcommand{\st}{\textnormal{ s.t. }} \newcommand{\bb}[1]{\mathbb{#1}} \newcommand{\var}[1]{\textnormal{#1}} \newcommand{\bld}[1]{\textbf{#1}} \newcommand{\flr}[1]{\left\lfloor#1\right\rfloor} \newcommand{\paren}[1]{\left(#1\right)} \newcommand{\sqb}[1]{\left[#1\right]} \newcommand{\ben}{\begin{enumerate}} \newcommand{\een}{\end{enumerate}} \begin{document} \section{Writeup} My code is divided into a fed discrete modules, each of which detailed below. \subsection{\texttt{read\_in} and \texttt{write\_out}} These two modules are dedicated to transforming data to and from the specified format. For improving testability, as many functions as possible work on data itself. Other than that, it's pretty mundane. Of note, I've chosen to represent distances and elevations as integer values rather than floating point. To ensure that no significant data is lost, we measure distances in millimeters and speeds is seconds per kilometer (or equivalently microseconds per meter). This was mostly done out of my strong distaste for floating point numbers, but seems to have benefitted performance slightly. \subsection{\texttt{a\_star}} This is where the actual routing algorithm lies, although not the heuristic nor the neighbor finding algorithm. The A* algorithm I've implement is pretty generic and works on any search space for which a neighbor function and a heuristic can be defined. It may be interesting to you that I've combined the cost and neighbor function. This mostly to make the code a little simpler. However, the core mechanics of the algorithm work nonetheless. I've also written the function \texttt{pathfind\_multi}, which is able to find a path which passes through several different checkpoints. This is the function which is ultimately called to perform pathfinding. This function simply repeatedly calls the normal \texttt{pathfind} function for each pair of adjacent goals. \subsection{\texttt{world}} Perhaps the most interesting part of the code, this module is what defines the search space, heuristic function, and neighbor function. Each node is simply represented by a tuple containing an X and a Y coordinate. When the \texttt{neighbor} function is called, these coordinates are looked up. Each adjacent node is evaluated, and a cost (in seconds) is produced for moving to any valid node, and the results are returned. More details about the specifics can be found in the detailed doccomment written for the \texttt{neighbor} function. This section also contains a heuristic function, which is considerably simpler. By looking only at the coordinates of the function, we can compute the minimum distance needed to be travelled between the two points. On a flat surface, this computation is exact. For performance, we leave out height from the computation. However, by assuming that all terrain is flat, we have not affected the admissibility of the heuristic. Real conditions will be equivalent or worse than the predicted measure. The last step in computing the heuristic is simply to convert between distance (in millimeters) and time (in microseconds). To do this, we just use the fastest speed possible, as to keep admissibility. In our implementation, this happens to be 500 microseconds per millimeter, the speed we have selected for \texttt{ROAD} terrain, and also a reasonable human jogging speed. \subsection{Conclusion} If this writeup has left you with any unanswered questions, I encourage you to look into the docstrings I've left in my code. Almost all functions defined for this project should be documented, and most have examples that you can run using doctesting. \end{document}