Before writing a computer program to solve a complex problem such as routing packets on the Internet, computing the similarity between two DNA sequences, or scheduling final exams at a university, a computer scientist must first design an *algorithm*. The typical design process consists of:

- Formulating a mathematically clean problem definition
- Proposing an algorithm
- Proving that it correctly solves the problem
- Analyzing its running time

Each of these steps is done with a high-level description of the problem and algorithm, before writing a single line of code! In this class, students will learn how to follow this process to design, analyze, and communicate precisely about algorithms. They will also learn about several algorithmic paradigms, including greedy algorithms, divide and conquer, dynamic programming, and network flow algorithms.

Finally, in some cases, the designer cannot find *any* efficient algorithm that solves the problem. Students will also learn the theory of NP-completeness and computational intractability, which lets them prove that certain problems are intractable.

Instructor | Dan Sheldon dsheldon (at) mtholyoke (dot) edu |

Lecture | Monday, Wednesday, 2:40pm–3:55pm |

Fourth Hour | Friday 2:15pm–3:05pm |

Location | Clapp 407 |

Gradescope | https://gradescope.com/courses/14999 |

Piazza | https://piazza.com/mtholyoke/spring2018/cs312/home |

Moodle | https://moodle.mtholyoke.edu/course/view.php?id=13192 |

Textbook | Kleinberg and Tardos, Algorithm Design, Addison-Wesley, 2006 |

Office Hours | Monday 4–5pm, Wednesday 12:15–1:15pm Or by appointment. |

TAs | Vivian Le and Kaya Ni |

TA office hours | TBD |