#!/usr/bin/env python # coding: utf-8 # In[4]: # setup from IPython.core.display import display,HTML display(HTML('')) display(HTML(open('rise.css').read())) # imports import numpy as np import matplotlib.pyplot as plt import seaborn as sns get_ipython().run_line_magic('matplotlib', 'inline') sns.set(style="whitegrid", font_scale=1.5, rc={'figure.figsize':(12, 6)}) # # CMPS 2200 # # Introduction to Algorithms # # ## Greedy Algorithms, Unit-Task Scheduling, Knapsack # # Today's agenda: # # - Framework for Greedy algorithms # - Unit-task Scheduling # - The Knapsack problem # # We previously looked at the Divide and Conquer framework. In this strategy, we used recurrences to give bounds on work/span and induction to prove correctness. # # We will now look at *Greedy* algorithms. The greedy framework is very simple: # # - Let $\mathcal{X}$ be possible choices for the solution. Initialize solution $S=\emptyset$. # - Select $x\in\mathcal{X}$ according to a greedy criterion $C(x)$ and set $S := S \cup \{x\}, \mathcal{X} := \mathcal{X} - \{x\}$. # - Repeat until solution is complete. # # Selection Sort was an example of a greedy strategy. What was the greedy criterion? Why was our algorithm correct? # # # For selection sort, we can see that swapping minimum element into the current position is a correct choice for the "optimal" solution. Moreover, selecting a minimum and sorting the rest of the list recursively is also correct. # In[5]: def selection_sort(L): if (len(L) == 1): return(L) else: m = L.index(min(L)) print('selecting minimum %s' % L[m]) L[0], L[m] = L[m], L[0] print('recursively sorting L=%s\n' % L[1:]) return [L[0]] + selection_sort(L[1:]) selection_sort([2, 1, 999, 4, 3]) # When would the greedy strategy yield the correct solution? # # 1. **Optimal substructure**: An optimal solution can be constructed from optimal solutions of smaller subproblems. # 2. **Greedy choice**: A greedy choice must be in some optimal solution (of a given size). # # Put together, these two properties yield that the iterative strategy above constructs an optimal solution. # # Due to their simplicity greedy algorithms are easy to implement. However proving the optimal substructure and greedy choice properties requires a problem-specific approach and can be tricky. # ### Unit Task Scheduling # # We already saw how a greedy scheduler could work to schedule concurrent tasks. However our greedy algorithm was not optimal. Let's consider the **unit task scheduling problem** where we are given a set of $n$ tasks $A = \{a_0, \ldots, a_{n-1}\}$. Each task $i$ has start and finish times $(s_i, f_i)$. The goal is to select a subset $S$ of tasks with no overlaps that is as large as possible. # #

# # Example: Let the tasks be $a_0=(0, 2), a_1=(2, 4), a_2=(4, 6), a_3=(2, 8)$. What is the largest set of non-overlapping tasks? # # # # Here, we should choose $S = \{a_0, a_1, a_2\}$ since choosing $a_3$ "blocks" a large part of the solution. # # Is there a greedy algorithm for the unit task scheduling problem? # # Does this problem have optimal substructure? What should the greedy choice be? # # **Optimal Substructure:** Since the tasks are nonoverlapping, if we identify one task in the optimal solution we can eliminate the tasks overlapping it and recursively solve for the remaining tasks. # # Is there a greedy criterion with the greedy choice property? # What if we chose the shortest task first? # # # # # What if we chose the task that started earliest? # # # # # What if we successively chose the task with fewest overlaps? # # # # # What if we chose the task that finished earliest? # # $a_0=(0, 2), a_1=(2, 4), a_2=(4, 6), a_3=(2, 8)$ # # This works on all of our counterexamples. # # What would the greedy choice property say here? # # **Greedy Choice Property**: For any set of tasks, the task with earliest finish time is in some optimal solution. # # **Proof**: Given a set of tasks $A$, let $G$ be the greedy solution and let $O$ be an optimal solution. Now, suppose that $G\neq O$. Sort the tasks by finish time and let tasks $a\in G$ and $a'\in O$ be the first pair of tasks with $a\neq a'$. So we have that $G = # \langle G_1, a, G_2\rangle$ and $O = \langle O_1, a', O_2\rangle$. Consider the solution $X = \langle G_1, a, O_2\rangle$. Since $G$ and $O$ are both valid solutions and $a$ has earlier finish time than $a'$, all the tasks in $O_2$ are compatible with $\langle G_1, a\rangle$. So we now have that $|X| = |O|$, which proves that $a$ is in some optimal solution. # # # # So we've proven that the earliest finish time first strategy produces the optimal solution. What about work/span? # # # # # Given a set of tasks, we can sort by earliest finish time in $O(n\log n)$ work and $O(\log^2 n)$ span. Then, we sequentially step through the tasks, adding a task to the solution if it doesn't overlap with a task that is already chosen. This takes $O(n)$ work/span. # ### The Knapsack Problem # # Let's look another optimization problem. Suppose there are $n$ objects, each with a *value* $v_i$ and *weight* $w_i$. You have a "knapsack" of capacity $W$ and want to fill it with a set of objects $X \subseteq [n]$ so that $w(X) \leq W$ and $v(X)$ is maximized. # # Example: Suppose you have 3 objects with values/weights $(10, 5), (6, 3), (6, 2)$ and $W=5$. # # |value|weight| # |------|-----| # |10 |5 | # |6 |3 | # |6 | 2 | # # What if we greedily took the most valuable object first? # # # What if we greedily took the object with highest per unit value (i.e., maximum value/weight ratio)? # # In the example above, we'd achieve a value of $12$, which is optimal. Does this always work? # Unfortunately no. Consider this counterexample with 2 objects that have weights/values $(10, 5), (9.999, 3)$. # # |value|weight| # |------|-----| # |10 |5 | # |9.999 |3 | # # # Is there another greedy criterion? # # # We don't know of one (we'll see more of this problem in the next module). The problem is that a greedy algorithm, regardless of the criterion selects objects one at a time, without factoring in the capacity remaining into future decisions. # # What if we wanted to solve the **fractional** version of the problem, where we could take arbitrary amounts of each item? # # Does our weight/value greedy criterion satisfy the greedy choice property? # # **Greedy Choice Property for Fractional Knapsaack**: The item $j$ with largest $v_j/w_j$ is in an optimal solution to the fractional knapsack problem. # # **Proof**: Suppose we were given $n$ objects and their weights/values. Let $O$ be the optimal solution, and let $G$ be the greedy solution. Let item $j$ have the maximum value/weight ratio. Suppose $j\not\in O$, but that some item $i$ had maximum ratio $v_i/w_i$ in $O$ and that $\alpha ~~(0\leq \alpha \leq 1)$ fraction was present. Now, $v_i/w_i \leq v_j/w_j$ so we can substitute the $\alpha$ fraction of item $i$ with item $j$ to obtain a solution $O'$ with $v(O') \geq v(O)$ that is also optimal. Thus item $j$ is in some optimal solution. # # How would we implement our solution? We sort by value/weight ratios and take successive items until we end with a possibly fractional item. The work is $O(n\lg n + n) = O(n\lg n)$ and the span is $O(\lg^2 n + n) = O(n)$. # In[ ]: