\documentclass[12pt,twoside]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\newcommand{\profs}{Professors Srini Devadas and Erik Demaine}
\newcommand{\subj}{6.006}
\newlength{\toppush}
\setlength{\toppush}{2\headheight}
\addtolength{\toppush}{\headsep}
\newcommand{\htitle}[3]{\noindent\vspace*{-\toppush}\newline\parbox{6.5in}
{\textit{Introduction to Algorithms: 6.006}\hfill\newline
Massachusetts Institute of Technology \hfill #3\newline
\profs\hfill Handout #1\vspace*{-.5ex}\newline
\mbox{}\hrulefill\mbox{}}\vspace*{1ex}\mbox{}\newline
\begin{center}{\Large\bf #2}\end{center}}
\newcommand{\handout}[3]{\thispagestyle{empty}
\markboth{Handout #1: #2}{Handout #1: #2}
\pagestyle{myheadings}\htitle{#1}{#2}{#3}}
\setlength{\oddsidemargin}{0pt}
\setlength{\evensidemargin}{0pt}
\setlength{\textwidth}{6.5in}
\setlength{\topmargin}{0in}
\setlength{\textheight}{8.5in}
\begin{document}
\handout{10}{Problem Set 5}{April 10, 2008}
\setlength{\parindent}{0pt}
\newcommand{\solution}{
\medskip
{\bf Solution:}
}
This problem set is due {\bf Thursday April 24} at {\bf 11:59PM}.
Solutions should be turned in through the course website in PDF form
using \LaTeX\ or scanned handwritten solutions.
A template for writing up solutions in \LaTeX\ is available on the
course website.
Remember, your goal is to communicate. Full credit will be given only
to the correct solution which is described clearly. Convoluted and
obtuse descriptions might receive low marks, even when they are
correct. Also, aim for concise solutions, as it will save you time
spent on write-ups, and also help you conceptualize the key idea of
the problem.
\medskip
\hrulefill
\medskip
Exercises are for extra practice and should not be turned in.
{\bf Exercises:}
\begin{itemize}
\item CLRS 24.1-1 (page 591)
\item CLRS 24.3-2 (page 600)
\item CLRS 24.3-4 (page 600)
\item CLRS 24.5-8 (page 614)
\item CLRS 24.3-6 (page 600)
\end{itemize}
\hrulefill
\begin{enumerate}
\item {\bf (15 points)} True or False.
Decide whether these statements are {\bf True} or {\bf False}. You
must briefly justify all your answers to receive full credit.
\begin{enumerate}
\item {\bf (5 points)} If some edge weights are negative, the
shortest paths from $s$ can be obtained by adding a constant $C$
to every edge weight, large enough to make all edge weights
nonnegative, and running Dijkstra's algorithm.
\item {\bf (5 points)} Let $P$ be a shortest path from some vertex
$s$ to some other vertex $t$. If the weight of each edge in the
graph is squared, $P$ remains a shortest path from $s$ to $t$.
\newpage
\item {\bf (5 points)} A \emph{longest simple path} from $s$ to $t$
is defined to be a path from $s$ to $t$ that does not contain
cycles, and has the largest possible weight.
Given a directed graph $G$ with nonnegative edge weights and two
nodes $s$ and $t$, the following algorithm can be used to either
find a longest simple path from $s$ to $t$, or determine that a
cycle is reachable from $s$:
\begin{itemize}
\item Negate all the edge weights.
\item Run Bellman-Ford on the new graph.
\item If Bellman-Ford finds a shortest path from $s$ to $t$,
return that as the longest simple path.
\item Otherwise, declare that a cycle is reachable from $s$.
\end{itemize}
Assume $t$ is reachable from $s$.
\end{enumerate}
\item {\bf (15 points)} Critical Edges.
You are given a graph $G=(V,E)$ a weight function $w:E \rightarrow
\Re$, and a source vertex $s$. Assume $w(e) \geq 0$ for all $e \in
E$.
We say that an edge $e$ is {\emph upwards critical} if by increasing
$w(e)$ by any $\epsilon > 0$ we increase the shortest path distance
from $s$ to some vertex $v \in V$.
We say that an edge $e$ is downwards critical if by decreasing
$w(e)$ by any $\epsilon >0$ we decrease the shortest path distance
from $s$ to some vertex $v \in V$ (however, by definition, if
$w(e)=0$ then $e$ is not downwards critical, because we can't
decrease its weight below 0).
\begin{enumerate}
\item {\bf (5 points)} Claim: an edge $(u,v)$ is downwards critical
if and only if there is a shortest path from $s$ to $v$ that ends
at $(u,v)$, and $w(u,v)>0$. Prove the claim above.
\item {\bf (5 points)} Make a claim similar to the one above, but
for upwards critical edges, and prove it.
\item {\bf (5 points)} Using the claims from the previous two parts,
give an $O(E \log V)$ time algorithm that finds all downwards
critical edges and all upwards critical edges in $G$.
\end{enumerate}
\newpage
\item {\bf (30 points)} Implementing Dijkstra.
\noindent The Howe \& Ser Moving Company is transporting the Caltech
Cannon from Caltech's campus to MIT's and wants to do so most
efficiently. Fortunately, you have at your disposal the National
Highway Planning Network (NHPN), packaged for you in
\verb|ps5_dijkstra.zip|. You can learn more about the NHPN at \\
\verb|http://www.fhwa.dot.gov/planning/nhpn/|
This data includes node and link text files from the NHPN. Open
\verb|nhpn.nod| and \verb|nhpn.lnk| in a text editor to get a sense
of how the data is stored (\verb|datadict.txt| has a more precise
description of the data fields and their meanings). To save you the
trouble of parsing these structures from a file, we have provided
you with a Python module \verb|nhpn.py| containing code to load the
text files into Node and Link objects. Read \verb|nhpn.py| to
understand the format of the Node and Link objects you will be
given.
Additionally, we have provided some tools to help you visualize the
output from your algorithms. You can use the \verb|Visualizer|
class to produce a KML (Google Earth) file. To view such a file on
Google Maps, place it in a web-accessible location, such as your
Athena \verb|Public| directory, and then search for its URL on
Google Maps.
For this problem, you will modify the file \verb|dijkstra.py|. As
you solve each part of the problem, check your work by running
\verb|test_dijkstra.py|. As usual, remember to comment your code,
including docstrings at the top of each function.
\begin{enumerate}
\item {\bf (3 points)} Write a short function
\verb|node_by_name(nodes, city, state)| to return a node from the
given city/state. Note that some nodes have a description which
isn't solely the city name, e.g. \verb|CAMBRIDGE NW| or
\verb|NORTH CAMBRIDGE|, either of which we would like to match a
query where \verb|city=='CAMBRIDGE'|. Given a choice of more than
one node, choose the first node that appears in the data.
\item {\bf (3 points)} The links you are given do not include
weights, so instead we will use the geographical positions of the
edge's nodes.
Write a function \verb|distance(node1, node2)| to return the
distance between two NHPN nodes. Nodes come with latitude and
longitude (in millionths of degrees). For simplicity, treat these
instead as $(x, y)$ coordinates on a flat surface, where the
distance between two points can be easily calculated using the
Pythagorean Theorem.
\emph{Hint:} You may find the \verb|math.hypot| function useful.
\item {\bf (24 points)} Implement Dijkstra's algorithm to find the
shortest path between two vertices in a graph with non-negative
edge weights.
Your function \verb|shortest_path(nodes, edges, weight, s, t)|
will be given a list of Node objects, a list of Edge objects
(undirected), a function \\ \verb|weight(node1, node2)| which
returns the weight of any edge between \verb|node1| and
\verb|node2|, a source Node $s$ and a destination Node $t$. Your
function should return a list of \verb|Node| objects representing
a path from $s$ to $t$.
Dijkstra's algorithm uses a priority queue, but this priority
queue has one subtle requirement not met by the \verb|heap.py|
implementation seen earlier in class. Dijkstra's algorithm calls
\verb|decrease_key|, but \verb|decrease_key| requires the index of
an item in the heap, and Dijkstra's algorithm would have no way of
knowing the current index corresponding to a particular Node. To
solve this problem, the course staff has written an augmented heap
object, \verb|heap_id|, with the following extra features:
\begin{itemize}
\item \verb|insert(key)| returns a unique ID.
\item A new method, \verb|decrease_key_using_id(ID, key)| takes an
\verb|ID| instead of an index.
\item A new method, \verb|extract_min_with_id()| extracts the minimum
element and returns a pair \verb|(key, ID)|
\end{itemize}
You may \verb|import heap_id|, without submitting the separate file.
\emph{Hint:} The format in which you are given the data (a list of
nodes, and a list of edges), is not what you want to use for
Dijkstra's algorithm. Start by preprocessing the data into a more
useful graph representation. Don't forget that the edges you are
given are undirected.
\item {\bf (Optional)} Included in \verb|nhpn.py| is a method to
convert a list of nodes to a \verb|.kml| file. \verb|.kml| files
can be viewed using Google Maps, by putting the file in a
web-accessible location (like your Athena Public directory), going
to \\ \verb|http://maps.google.com| and putting the URL in the
search box.
Run \verb|visualize_path.py|. This will create two files,
\verb|path_flat.kml| and \\ \verb|path_curved.kml|. Both should be
paths from Pasadena CA to Cambridge MA. \verb|path_flat.kml| was
created using the distance function you wrote in part (b), and
\verb|path_curved.kml| was created using a distance function that
does not assume the Earth is flat. Can you explain the
differences? Also, try asking Google Maps for driving directions
from Caltech to MIT to get a sense of how similar their answer is.
\end{enumerate}
\end{enumerate}
\end{document}