... start recording.

Questions?

(This yellow & black image is one I generated last night ... its a maze generated by graph search! Stay tuned ...)

We're working now on understanding trees and graphs : what they are, how to work with them in a computer program, and how to search through them.

These things get used in many ways in computing, including as building blocks for databases and storage and lookup systems, and for searching among alternatives when planning or figuring out how to play chess or which roads to take to get to your destination.

I've posted my answers to the homework ; we should talk through those, particularly what "doing it by hand" means. (Hint: you should still be using a fringe, pushing, popping, and all that ... just writing everything down as you simulate what the computer would do.)

I've also added a link in the "students" menu to the online graphviz tool I mentioned last time.

- Graph theory - mathy definition of a graph
- Tree (data structure)
- Tree (graph theory)

Here's a summary of the material we're working on.

The usual terminology when working with graphs is that they are composed of "vertices" and "edges". Each vertex has "neighbors" that are reached along the edges.

```
A - B a graph : 6 vertices are {A, B, C, D, E, F}
| | 6 edges are { A-B, A-C, B-D, C-D, D-E, C-F }
C - D - E
| this one is : undirected (i.e. no arrows)
F cyclic (i.e. there are loops)
unweighted (i.e. no numbers attached to the edges)
```

The usual terminology when thinking of something as a tree is that it is composed of "nodes" which have "children" which are "below" each "parent".

```
A a tree : 5 nodes are {A, B, C, D, E}
/ \ each node (except root) has 1 parent and may have children
B C children_of(A) = {B, C}
/ \ parent_of(E) = C
D E
```

quick quiz :

- Is a linked list a graph?
- Is a linked list a tree?
- Is a tree always a graph?
- Is a graph always a tree?

"Tree" and "graph" are broad ideas, not really concrete data structures. But those ideas are used in many data structures, and in algorithms as well.

For an indexed array `data[i]`

or a linked list `d0 -> d1 -> d2`

, visiting
everything - searching for something or doing something to each - is straightforward.
Each element has a "before" and "after"; you just start at the beginning and
do each one in turn.

But for trees and graphs, visiting everything is trickier.

- graph search or "graph traversal"
- tree search or "tree traversal"

The three big ideas we're considering now for visiting all parts of a graph are

- recursive depth-first (trees)
- depth-first with a loop and fringe (but may go too far away without looking close by)
- breadth-first with a loop and a fringe (but may take a lot of storage)

There are other variations of these ideas; which option is best depends on the situation, including

- iterative deepening (i.e. many depth-first searches, successively deeper)
- backtracking (i.e. "undoing" edge moves; can minimize storage and forget unsuccessful branches)

For pseudo-code for depth-first search with a fringe, see for example

It turns out that these same graph search ideas can be used to both generate mazes, and to solve mazes. And doing so can give some insight into how these different sorts of searches work.

I have written some code to illustrate these ideas (and one more search algorithm) and made lots of pretty pictures which I will show you, all in code/graphs/maze/ .

For more on all this topic see

- wikipedia: Maze generation algorithm
- wikipedia: Maze-solving algorithm
- maze algorithms
- mazelib - A Python API for creating and solving mazes.
- google "maze algorithm" or "python maze algorithm"

Anyone want to write a maze solving program?

There are many, many algorithms, and our job is not to see all of them. Instead what you should be trying to learn is the ideas that they have in common :

(1) We use data structures with APIs (interfaces) that are convenient for the problem, and which give us an way to get information (like "neighbors of" or "is have we seen this before") in an efficient way (i.e. O(1) if we can).

(2) Most algorithms involve some sort of "search" like we're looking at here, almost always an explicit or recursive loop.

I would next like to look at four "shortest path" graph algorithms, which do two different "shortest" problems in two different ways.

There are a number of algorithms to find various "shortest" graph properties. Below are a few of the well known ones.

Some of these are in the text, others we may do with other resources. Remembering the details isn't the main point, instead I would like you to get exposed to what sorts of techniques are out there.

Notice that they commonly use the data structures that we've already discussed (such as stacks, queues, binary heaps). Note also that there are tradeoffs in the O() behavior, and that different algorithms may be better depending on the qualities (such as sparseness) of the graph.

There's a longer list of classic graph problems https://en.wikipedia.org/wiki/Graph_theory .

- wikipedia: minimum spanning tree
- Prim's algorithm (wikipedia)
- Kruskal's algorithm (wikipedia)
- comparison

- wikipedia: shortest path problem
- Dijkstra's algorithm (wikipedia)
- Floyd-Warshall algorithm (wikipedia)
- comparison

I'd like us to look at and understand the ideas behind all four of those.

One commonly studied extension of Dijkstra's algorithm is A* which tries to find the shortest path when there is some additional information available, beyond what is just given in the graph. This extra information is often the physical distance to some other point, so that you can guess in which order to try different paths ... even if your guesses might be wrong if there are things in the way.

The last "search" algorithm I'd like us to study is that used in looking ahead in puzzles or games like tic-tac-toe. In these situation, each position is a node in a tree, and we're trying to look ahead to find the moves that leave us in a better position or solve the puzzle.

Typically there are two things that you need to do :

- implement the game itself, enough to simulate it in a way that can
- evaluate a position (i.e. "is this solved")
- generate neighboring "one move away" positions

- choose, implement, and test a search strategy

In about two weeks, I'm going to ask each of you to choose a final project - a problem with an associated algorithm to solve it that you will research, implement, analyze, and write a short paper on. Like the midterm project, but more open ended. I'll come up with a list of reasonable choices, but be thinking about that.

In the last few weeks of the term, while you're mostly working on your projects, we'll look at a few more topics. The ones I'm leaning towards are

- databases, SQL (structured query language), and B-trees : O(log n) add, remove, search for big collections.
- P vs NP : a summary of complexity theory

In both cases these would be "see some of the big ideas and get a taste of", since they're both large topics.

... is posted. ;)

- Explore the four "shortest" algorithms that I list above, using any online sources you can find.
- What is the "shortest path" problem?

- Take a look at my
- Start thinking about what you'd like to do for a final project.

https://cs.bennington.college /courses /spring2021 /algorithms /notes /graphs3

last modified Thu April 15 2021 3:41 pm

last modified Thu April 15 2021 3:41 pm