Week 13: Exercises

1. Graph Paths

In Haskell, we may represent a graph in adjacency-list representation using an association list that maps each vertex to a list of its neighbors:

type Graph a = [(a, [a])]

For example, consider this undirected graph:

We may represent it as

graph = [ ('a', "ce"), ('b', "de"), ('c', "adf"), ('d', "bcef"),

 ('e', "bdf"), ('f', "cdeg"), ('g', "f") ]

a) Write a function

adjacent :: Eq a => Graph a -> a -> [a]

that returns a list of a vertex's neighbors in a graph.

b) Write a function

paths :: Eq a => Graph a -> a -> a -> [[a]]

that takes a graph and the ids of start and end vertices v and w, and returns a list of all possible paths from v to w, where a path is represented as a list of vertices. A path may not contain the same vertex twice.

2. Depth-First Search

Write a function

dfs :: Eq a => Graph a -> a -> [a]

that takes a graph and the id of a start vertex v, and returns a list of all vertices that are reachable from v. Use a depth-first search. Write the function two ways: (a) using recursion to explore the graph; (b) using a stack data structure.

3. Cycle

a) Write a function that takes a directed graph and returns True if the graph is cyclic, otherwise False.

b) Modify your function to work on an undirected graph.

4. Breadth-First Search

Write a function that takes a graph and the ids of start and end vertices v and w, and returns a list of vertices on the shortest path from v to w, or Nothing if there is no such path. Use a breadth-first search.

5. Hamiltonian Path

In an undirected graph, a Hamiltonian path is a path that visits every vertex exactly once.

Write a function that takes a graph in adjacency-list representation and returns a list of all Hamiltonian paths in the graph.

6. Graph Isomorphism

Write a function that takes two graphs in adjacency list representation and returns true if the graphs are isomorphic.