\documentclass[10pt]{article}
\usepackage{times,graphicx,epstopdf,fancyhdr,amsfonts,amsthm,amsmath,url,algorithm,algorithmic,xspace}
\usepackage[left=.75in,top=.75in,right=.75in,bottom=.75in]{geometry}
%\usepackage{tweaklist} % to tweak list spacings
\textwidth 7in
\textheight 9.5in
\pagestyle{fancy}
\begin{document}
\newtheorem{claim}{Claim}
\newtheorem{definition}{Definition}
\newtheorem{theorem}{Theorem}
\newtheorem{lemma}{Lemma}
\newtheorem{observation}{Observation}
\newtheorem{question}{Question}
%\renewcommand{\itemhook}{\setlength{\topsep}{5pt}%
%\setlength{\itemsep}{0pt}}
% Comment out for single spacing
%\baselineskip 20pt
\lhead{Williams College}
\chead{Homework 8}
\rhead{Brent Heeringa}
\cfoot{Algorithm Design and Analysis - CS 256}
\lfoot{Due: 11.00, 03 May 2013}
\rfoot{\thepage}
\renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\headwidth}{\textwidth}
\renewcommand{\footrulewidth}{0.4pt}
\begin{question} \label{q:coin}
Suppose you have a biased coin that, when flipped, takes on heads with unknown probability $p$ and tails with probability $1-p$. Show how to use this coin to construct a string of $n$ independent bits such that each bit is equally likely to be a 0 or a 1. In other words, show how to use this coin to construct an algorithm that, when run, behaves like an unbiased coin. What is the expected running time of your algorithm as a function of $p$?
\end{question}
\begin{question}[Inspired by Dave Moore '10] \label{q:dmoore}
Imagine a procedure {\sc Random}$(a,b)$ that, when called, returns an integer between $a$ and $b$ inclusively and uniformly at random. That is, each integer in the range $[a,b]$ is equally likely to appear on a call to {\sc Random}$(a,b)$. Now, suppose you have a fair coin. Describe an implementation of {\sc Random}$(a,b)$ that is only allowed to flip this coin (i.e., it can't use any other source of randomness). What is the expected running time of your procedure, as a function of $a$ and $b$?
\end{question}
\begin{question}
Suppose you have the same biased coin as in Question~\ref{q:coin}, however, this time you don't wish to construct an algorithm to produce an unbiased coin (i.e. a coin with probability 1/2 of coming up heads) but rather another unbiased coin with some given probability $q$ of coming up heads. Show how to use your coin to construct an algorithm that, when run, behaves like a biased coin with probability $q$ of returning heads. You may assume that $q$ is a rational number. Can your solution to Question~\ref{q:dmoore} help?
\end{question}
\begin{question}[JE]
Suppose you have a set of $n$ complementary nuts and bolts where the size of each pair is unique. Consider the following randomized algorithm for choosing the largest bolt. Draw a bolt uniformly at random from the set of n bolts, and draw a nut uniformly at random from the set of n nuts. If the bolt is smaller than the nut, discard the bolt, draw a new bolt uniformly at random from the unchosen bolts, and repeat. Otherwise, discard the nut, draw a new nut uniformly at random from the unchosen nuts, and repeat. Stop either when every nut has been discarded, or every bolt except the one in your hand has been discarded. What is the exact expected number of nut-bolt tests performed by this algorithm? Prove your answer is correct. [{\em Hint: What is the expected number of unchosen nuts and bolts when the algorithm terminates?}]
\end{question}
\begin{question}[Extra Credit]
This question asks you to implement a skip list in Java. Recall that a skip list is a collection of linked lists, organized by level. Every item in the list appears at level 0. Items appear at successive levels with geometrically diminishing probability. Our skip list will take advantage of two boundaries along the left and right edges of the skip list, as well as a boundary above the highest level of the skip list. These boundaries will make finding, inserting, and removing items easier. Here's a picture of a skip list with values 13, 34, and 79.
\begin{center}
\includegraphics[width=.5\linewidth]{figures/skiplist}
\end{center}
\subsubsection*{Addition}
Recall that after an item is inserted at level 0, it is promoted to level 1 with probability 1/2. The process then repeats itself. In general, an item at level $i$ is promoted to level $i+1$ with probability 1/2. However, an item is never promoted above the top boundary. In fact, we always have an upper boundary that never contains any egers. If an item is ever promoted to the upper boundary, we immediately take away its coin (so that it can't be promoted anymore), and add a new upper boundary. For example, say we insert the value $-3$ into an empty skip list.
\begin{center}
\includegraphics[width=.2\linewidth]{figures/empty-skiplist}
\end{center}
Notice that level 0 has an upper boundary. We first find the correct node on level 0 (this node should have the largest value not exceeding -3).
\begin{center}
\includegraphics[width=.2\linewidth]{figures/empty-skiplist-A}
\end{center}
We then insert a new node with value -3 and update the appropriate pointers.
\begin{center}
\includegraphics[width=.2\linewidth]{figures/empty-skiplist-B}
\end{center}
Next, we flip a coin. Say it ends up heads. Then we promote -3 to the next level.
\begin{center}
\includegraphics[width=.2\linewidth]{figures/empty-skiplist-C}
\end{center}
However, since -3 has reached the top boundary, we steal its coin away and no longer allow it promotion. Furthermore, we add a new upper boundary.
\begin{center}
\includegraphics[width=.2\linewidth]{figures/empty-skiplist-D}
\end{center}
\subsubsection*{Removal}
Removing a node is similar. However, beware of superfluous upper boundaries. That is, we should never see a skip list like this.
\begin{center}
\includegraphics[width=.2\linewidth]{figures/superfluous-skiplist}
\end{center}
\subsubsection*{Implementation}
You should implement a skip list as described above. Use {\tt turnin} to turn in your {\tt SkipList.java} file. Please note and adhere to the following:
\begin{itemize}
\item Your skip list should be a Java class called {\tt SkipList}. It should be placed inside a file called {\tt SkipList.java}.
\item Your skip list is generic---it should be parameterized by some type {\tt T} which is {\tt Comparable}. The type {\tt T} is the type of the values stored in the skip list.
\item Starter code is provided on the website. It contains a sparse skeleton of the {\tt SkipList} class as well as moderate skeletons of three inner private classes {\tt Node}, {\tt LeftBoundaryNode}, and {\tt RightBoundaryNode}. Feel free to use the starter code or ignore it. However, your final code {\bf must} adhere to the constraints outlined herein. Note that the starter code uses a {\tt Node} class with pointers in all four directions. {\tt null} is the default value of these pointers. The default {\tt value} of a node is also {\tt null}.
\item Do not place your code inside a specific package.
\item Your {\tt SkipList} class should {\em not} contain a {\tt main} method when you turn it in. That said, you will find a {\tt main} method helpful when testing.
\item Your {\tt SkipList} class should support the following methods:
\begin{enumerate}
\item {\tt public boolean add(T i)} where the return value indicates if the addition was successful (duplicate elements are not allowed).
\item {\tt public boolean remove(T i)} where the return value indicates if the removal was successful.
\item {\tt public boolean contains(T i)}
\item {\tt public T predecessor(T i)} -- returns the largest item less than or equal $i$ in the skip list. Note that $i$ may not be in the skip list. This is called {\tt floor} in Java's {\tt TreeSet}.
\item {\tt public T successor(T i)} -- return the smallest item greater than or equal to $i$ in the skip list. Note that $i$ may not be in the skip list. This is called {\tt ceiling} in Java's {\tt TreeSet}.
\item {\tt public int size()} -- return the number of items in level 0 (boundary nodes don't count). Do not return the number of nodes in the skip list.
\end{enumerate}
\item Duplicate items are not permitted in the skip list.
\item Use the {\tt nextBoolean()} method of the {\tt Random} class for coin flips.
\item The starter code seeds the random number generator with 47. Your code should match the given example output if you maintain this seed.
\end{itemize}
Running your completed code with the following {\tt main} method
\begin{verbatim}
public static void main(String[] args) {
SkipList l = new SkipList();
System.out.println(l);
l.add(new Integer(-1000));
System.out.println(l);
l.add(new Integer(3000));
System.out.println(l);
}
\end{verbatim}
should produce the following output
\begin{tiny}
\begin{verbatim}
assonance:SkipLists heeringa$ java -Xms512m -Xmx1024m SkipList
[ L ] -- [ R ]
[ L ] -- [ R ]
[ L ] -- [ R ]
[ L ] -- [ -1000 ] -- [ R ]
[ L ] -- [ -1000 ] -- [ R ]
[ L ] -- [ R ]
[ L ] -- [ -1000 ] -- [ R ]
[ L ] -- [ -1000 ] -- [ 3000 ] -- [ R ]
\end{verbatim}
\end{tiny}
The {\tt -Xms512m -Xmx1024m} arguments to the java virtual machine tell it that the minimum heap size should be 512 MB and the maximum heap size should be 1024 MB.
\subsubsection*{Experiments}
William Pugh, the creator of skip lists, reports that the randomized data structure offers comparable if not better performance than red-black trees. We should test this claim (albeit modestly) using your implementation and the Java {\tt TreeSet} class which is (conveniently) implemented using a red-black tree. Use the following syntax to create a {\tt TreeSet} of integers:
\begin{verbatim}
TreeSet set = new TreeSet();
\end{verbatim}
Notice that we must use the Java Object type {\tt Integer} rather than the primitive {\tt int}. To add an integer, use:
\begin{verbatim}
set.add(new Integer(-3));
\end{verbatim}
More information about the Java {\tt TreeSet} class is available at {\tt http://download.oracle.com/javase/6/docs/api/java/util/TreeSet.html}.
Perform the following experiments (you probably want to disable the JIT by using {\tt -Xint} as an additional flag to the Java interpreter:
\begin{enumerate}
\item Insert 50,000 random integers into your skip list. Insert the same integers into a Java {\tt TreeSet}. Report on the total and average insertion time for both data structures. Draw conclusions. You may find\\ {\tt System.currentTimeMillis()} helpful. Recall that duplicates are not allowed, so your sets will likely have size less than 50,000.
\item Now insert an additional random 50,000 integers into your skip list. Insert the same integers into the {\tt TreeSet}. Both data structures should have the same size. Now delete the first 50,000 integers (some of these deletions may not be possible which is okay since your remove method will report that no deletion occurred). Report on the total and average removal time for both data structures. Draw conclusions.
\item Perform one well motivated experiment of your own design. Describe it in detail and report on the results.
\end{enumerate}
\end{question}
\end{document}