Title: More on Graphs
1More on Graphs
2Outline
- Prerequisites
- Tail Recursion
- Intro to Graphs
- Objectives
- Graphs with Weights
- Breadth-First Search
- Path finding
- Minimal Spanning Trees
- Reference
- none
3(No Transcript)
4(No Transcript)
5(No Transcript)
6Map of Distilleries in Scotland. Is this
a graph? (What is a graph?) Does this
provide useful information? Whats missing?
7Graph/Network Uses
- Graphs can also track the flows and movements of
individuals in society. - E.g., Krempels map of Duisburg zoo visitors.
The width of the lines indicates the number of
visitors taking an edge.
(Note the Autobahn divides the zoo in half. Can
you see evidence of this in the graph?)
8(No Transcript)
9Review Graphs (contd)
Graphs are also useful for modeling hierarchy
networks. A good example is the internet, with
various tiers of providers that link portions
of the net together. A graph can be used to
model the network relationship between computers.
10(No Transcript)
11(No Transcript)
12Depth First Search
The simplest form of search in a hierarchical or
network structure is called "depth-first search".
We can write an algorithm for a depth-first
search on a binary tree DFS (depth first
search) 1. Look at the root 2. If it's
what you're looking for, then return success
3. If the root has no descendants, then return
failure 4. Call df-search on the subtree
whose root is the leftmost descendant and return
success if that search is successful 5. Call
df-search on the subtree whose root is the
rightmost descendant and return success if that
search is successful
13Simple Graph Representation
Lets take a simple graph, and try to draw a
Scheme-like list that represents its data.
14Representing Graphs
(define graph '((A (B E F)) (B (A C D E)) (C
(B D)) (D (B C E)) (E (A B D F)) (F (A E))))
A
B
E
F
E
D
E
F
C
A
A
15Problems with Simple Representation
- No representation of edge weight
- No representation of graph continuity
- Finding node edges requires recursive search
- (first (second (rest (first graph)))) !!!
- Probably much more
16Problems Searching Graphs
Problem What if a node has more than one
child? Our previous algorithms just considered
three items node, left and right. Problem
What if we cycle?
Lets learn more about searching first.
17Depth-First Search using Weighted Edges
Data Analysis - a graph is a collection of
zero or more nodes a node is a structure
containing a data item and a
list-of-children where the data item
may be any legal Scheme construct (define-struct
node (data children)) and the
list-of-children is a list defined as follows
a list-of-children is either empty
or the cons of a link onto a list-of-children
a link is either false (if a link does not
exist) or a structure containing a
weight and a node (define-struct link (weight
node)) Test (define wilma (make-node 'wilma
empty)) (define harriet (make-node 'harriet
empty)) (define bamm-bamm (make-node
'bamm-bamm (list (make-link 1 betty)
(make-link 1 barney)))) (define gen-y
(make-node 'gen-y (list (make-link 1 gen-x)
(make-link 1 beaver))))
Gen-y
Gen-x
Pebbles
Bamm-Bamm
Wilma
Fred
Barney
Betty
18Tail Recursive DFS
(define (dfs here target) (local (
Contract dfs-helper node target trail -gt
list-of-data Purpose find a
depth-first path to the target (define
(dfs-helper here target trail) (cond
(equal? (node-data here) target) trail
else (find-on-children (node-children
here)
target
trail))) continued
19Tail Recursive DFS
still inside (local ) Contract
find-on-children list-of-links target trail
-gt list-of-data
Purpose find a path from a list of links
(define (find-on-children lst target
trail) (cond (empty? lst) empty
else (local ((define this-link
(first lst))
(define next-node (link-node this-link))
(define next-name
(node-data next-node))
(define this-ans
(dfs-helper (link-node this-link)
target
(cons
next-name trail)))) (if
(empty? this-ans)
(find-on-children (rest lst) target trail)
this-ans)))))
(dfs-helper here target (list (node-data here)))))
20dfs-weight.scm
21Questions?
22Queues
23Some Examples
- Waiting in line
- At the grocery store
- At the movies
- Printer queue
- Ordering items
- Bills to pay
- Making pizzas
- We can use a queue to model each of these.
24The Queue
Dequeue
Enqueue
25Properties of Queues
- Idea a First In, First Out (FIFO) data
structure - Behaviors
- Enqueue Add to end of queue
- Dequeue Remove from front of queue (and return
that front value) - Front Return front-most item (but leave it in
the queue) - Is_Full is it full?
- Is_Empty is it empty?
- Initialize empty queue
26The Queue as a Logical Data Structure
- The queue is an idea
- It implies a set of logical behaviors
- It can be implemented various ways
- Using a linked list or a tree or an array
- In this example, well focus on dynamic
implementations using dynamic data...
27QueuesDynamic Implementation
- A list with restricted set of operations to
change its state only modified by adding to one
end and deleting from the other.
28Queue Implementation in Scheme
- We will provide you with a Scheme module having
the specific characteristics of a queue without
telling you at the moment how these
characteristics are achieved. - The module will have the following capabilities
- (define my-queue empty)
- (start-q)
- (enqueue 1)
- (enqueue 'b)
- (enqueue false)
- (not (q-empty?))
- ( (dequeue) 1)
- (symbol? (dequeue) 'b)
- (not (dequeue))
- (q-empty?)
29Questions?
30Breadth-First Search
31Breadth-First Search
Another common search strategy is called a
breadth-first search (BFS). This search
performs a methodical check of adjacent nodes,
with preference given to the most recently
discovered nodes. That is, unlike a DFS, which
races down the graph, discovering new paths at
each turn, a BFS will visit each node at the
level at which they are discovered.
32BFS Traversal
Lets trace a BFS traversal of a graph, to
see how it might be implemented.
33Graphs Searching
Lets perform an inductive analysis of a search,
and figure out how it works. We can then model
this in code.
Given this graph
Lets see if there exists a path from A to
G. (Of course theres a path. We can see that.
But how can a computer determine this?)
34Graphs Searching
We will perform a BFS. We are first given
our start node, A, which we can designate as
the current node we are visiting.
35Graphs Searching
We have some way of fetching the current nodes
adjacencies.
A
B
C
F
E
D
G
36Graphs Searching
In a linked list or tree, we had a set number
of links or children, so exploring them all
was easy--just write a line of code to visit each
child or adjacent node.
A
B
C
F
E
D
G
But in a graph, each node has a variable number
of nodes. We need a set or list to manage the
nodes we discover, but have not explored
Current Node
A
37Graphs Searching
So we use a queue, since this is BFS. A DFS
would have used a stack instead.
A
B
C
F
E
Open Nodes
D
G
F
B
Current Node
We place the current nodes adjacencies in this
list of open, unexplored nodes
A
Adjacencies
F
B
38Graphs Searching
At this point, are done with the current
node, and are ready to move on to the first node
in the open list.
A
B
C
F
E
Open Nodes
D
G
F
B
Current Node
But wait! Maybe we should keep a list of nodes
weve already visited, so we dont return to them
again.
A
39Graphs Searching
A
B
C
A
F
E
Open Nodes
D
G
B
So we make a list to hold the nodes weve
visited, and insert A into this list. Our
current node is now F. The node F is not the
goal...
Current Node
F
40Graphs Searching
A
B
C
A
F
E
Open Nodes
D
G
B
Current Node
... so, we fetch the adjacencies to our new
current node.
F
41Graphs Searching
A
B
C
A
F
E
Open Nodes
D
G
B
D
E
A
Current Node
We prepare to copy the new adjacencies to our
queue of open nodes . . .
F
Adjacencies
D
E
A
42Graphs Searching
A
B
C
A
F
E
Open Nodes
D
G
B
D
E
A
Current Node
BUT WAIT! We already visited node A. Dont
place it in the open queue.
F
Adjacencies
F
B
A
43Graphs Searching
A
B
C
A
F
F
E
Open Nodes
D
G
B
D
E
Current Node
All done with F. Move it up to the visited
list. Lets check out B, the next node on our
open queue.
F
44Graphs Searching
A
B
C
A
F
F
E
Open Nodes
D
G
D
E
Current Node
What can we discover from B? We fetch its list of
adjacent nodes.
B
45Graphs Searching
A
B
C
A
F
F
E
Open Nodes
D
G
D
E
C
Once again, our list of visited nodes saves us
from a cycle in our search
Current Node
B
46Graphs Searching
A
B
C
A
F
B
F
E
Open Nodes
D
G
D
E
C
Current Node
Were done with B. Promote it to our visited
list. Swear in your next witness.
B
47Graphs Searching
A
B
C
A
F
B
F
E
Open Nodes
D
G
E
C
Were now at D.
Current Node
D
48Graphs Searching
A
B
C
A
F
B
D
F
E
Open Nodes
D
G
E
C
Current Node
Were done with D, so place a reference in our
visited list. E is next up.
D
49Graphs Searching
A
B
C
A
F
B
D
F
E
Open Nodes
D
G
C
We find that E is adjacent to F, C, G.
Current Node
E
50Graphs Searching
A
B
C
A
F
B
D
F
E
Open Nodes
D
G
C
C
G
We copy these references to our open queue. The
F node is omitted, since weve seen it already.
Current Node
E
51Graphs Searching
Wait a minute. Cant we quit yet?
A
B
C
A
F
B
D
F
E
Open Nodes
D
G
C
C
G
Arent we done yet? No. Were close, but a
simple, plain-vanilla BFS would not check to see
if the newly enqueued nodes include the goal
node. Well find it soon enough.
Current Node
E
52Graphs Searching
Wait a minute. There are two open C nodes
A
B
C
A
F
B
D
F
E
Open Nodes
D
G
C
C
G
Question Dont we want to purge the duplicate C
nodes?
Current Node
Answer NO! Duplicates are harmless, since we
check for cycles. Plus, these nodes were
contributed by different nodes. As will be seen
shortly, this is the key to returning a path.
E
53Graphs Searching
This is an important point remember this!
A
B
C
A
F
B
D
F
E
Open Nodes
D
G
C
C
G
Question Dont we want to purge the duplicate C
nodes?
Current Node
Answer NO! Duplicates are harmless, since we
check for cycles. Plus, these nodes were
contributed by different nodes. As will be seen
shortly, this is the key to returning a path.
E
54Graphs Searching
A
B
C
A
F
B
D
E
F
E
Open Nodes
D
G
C
C
G
Current Node
Were done with E. Promote it to the visited
list.
E
55Graphs Searching
A
B
C
A
F
B
D
E
F
E
Open Nodes
D
G
C
G
Current Node
What does C contribute?
C
56Graphs Searching
A
B
C
A
F
B
D
E
F
E
Open Nodes
D
G
C
G
G
What does C contribute?
Current Node
C
Another link to G, but from another path the
rest cycle
57Graphs Searching
A
B
C
A
F
B
D
E
F
E
Open Nodes
D
G
C
G
G
Current Node
Were done with C. The next node up is C again.
C
58Graphs Searching
A
B
C
A
F
B
D
E
C
F
E
Open Nodes
D
G
G
G
C has just been done, so theres nothing new
it can add . . . The next node up is ...
Current Node
C
59Graphs Searching
A
B
C
A
F
B
D
E
C
F
E
Open Nodes
D
G
G
Current Node
G, the goal node. Were done.
G
60Whew.
61Observations
We used a queue for a BFS.
Open Nodes
D
B
C
If we instead had used a stack, we would have
performed a DFS.
C
This sometimes results in a different path,
although both DFS and BFS are exhaustive
searches. If theres a path, either will find it.
B
D
62BFS Step-by-Step
BFS, because it uses a queue, will examine all
nodes one step away, then two steps away, then
three, etc.
A
B
C
F
E
D
G
63DFS Leap then Look
Because it uses a stack, when the DFS discovers a
new node, then races down that branch . . .
A
B
C
F
E
D
G
Only if it hits a dead end will it back up and
examine other adjacent nodes.
64Implementation
From our study, we could code a method in
Scheme. Its easy to see that some of our
structures correspond to Scheme data structures.
(a f b d c)
(g e) need (insert-queue) function
Node (parameter)
65BFS Implementation
Contract bfs symbol node -gt boolean (define
(bfs item start) (local ( Contract
bfs-helper symbol -gt boolean (define
(bfs-helper item) (if (q-empty?)
false (local ((define
here (dequeue))) (if
(this-is-it here item)
true (begin
(store-children here)
(bfs-helper item)))))) continued
66BFS Implementation
still in local Contract
store-children node -gt
enqueued children nodes (define
(store-children nd)
(store-child-helper (node-children nd)))
Contract store-child-helper (listof links)
-gt enqueued child
(define (store-child-helper lst)
(if (empty? lst) false
(local ((define this-link (first lst)))
(begin (enqueue
(link-node this-link))
(store-child-helper (rest lst))))))
Contract this-is-it node symbol -gt
boolean (define (this-is-it nd nm)
(symbol? nm (node-data nd)))) (begin
(start-q) (enqueue start)
(bfs-helper item))))
67bfs
68Final Thoughts
- This code used a simple family tree
- It therefore didnt worry about cycles
- It also didnt worry about computing a history
- It did, however, give us an opportunity to check
a hypothesis - If we claim we can convert from BFS to DFS merely
by replacing the queue with a stack, why not try
it
69dfs-stack
70Summary
- You Should Now Know
- Basic Graph Terminology
- Depth-First Search
- Breadth-First Search
71(No Transcript)