CS 4104 Algorithms Notes
- Published on
- ∘ 183 min read ∘ ––– views
Previous Article
Next Article
Contents
- 00 - Introduction
- 01 - Stable Matching
- 02 - Analysis of Algorithms
- 03 - Review of Graphs and Priority Queues
- 04 - Linear Time Algoirthms
- 05 - Greedy Algorithms
- 06 - Greedy Graph Algorithms
- 07 - Applications of Minimum Spanning Trees
- 08 - Divide and Conquer Algorithms
- 09 - Dynamic Programming
- 10 - Network Flow
- 11 - Network Flow Applications
- 12 - NP and Computational Tractibility
- 13 - NP-Complete Problems
- 14 - Coping with NP-Completeness
- 15 - Solutions
Introduction
Notes from CS 4104 with exercises and derivations from "Algorithm Design" by Kleinberg and Tardos.
Glossary
Term | Definition |
---|---|
Matching | each man is paired with ≤ 1 woman and vice versa |
Perfect Matching | each man is paired with exactly 1 woman and vice versa |
Rogue Couple | a man and a woman who are not matched, but prefer each other to their |
Stable Matching | a perfect matching without any roogue couples |
polynomial running time | if there exists constants such that , the running time is bounded by |
Asymptotic Upper Bound | a function is if there exists constants s.t. |
Asymptotic Lower Bound | a function is if there exist constants s.t. |
Asymptotic Tight Bound | a function is if is and is |
Euler Path | Only possible if the number of nodes with odd degree is at most 2 |
A path | in an undirected graph is a sequence of nodes s.t. every consecutive pair of nodes is connected by an edge |
simple path | all its nodes are distinct |
cycle | is a path where , the first nodes are distinct and |
connected undirected graph | for every pair of nodes , there is a path from to in |
distance | the minimum number of edges in any path |
connected component of containing | the set of all nodes such that there is an path in |
Adjaceny Matrix | boolean matrix, where the entry in row , col is 1 iff the graph contains the edge |
Adjaceny List | array , where stores the list of all nodes adjacent to |
bipartite | A graph is bipartite if can be partitioned into two subsets such that every edge in has one endpoint in and one in |
Greedy algorithm | makes the best current choice without looking back. Assume the choices made prior were perfect |
inversion | A schedule has an inversion if a job with a deadline is scheduled before another job with an earlier deadline i.e. |
spanning tree | A subset is a spanning tree of if is a tree |
01 - Stable Matching
Problem
Each man ranks all the women in order of preference
Each woman ranks all the men in order of preference
Each person uses all ranks from s.t. there are no ties or incomplete lists
Male preference matrix:
1 | 2 | 3 | 4 | |
4 | 3 | 1 | 2 | |
4 | 3 | 1 | 2 | |
3 | 1 | 4 | 2 |
Female preference matrix:
1 | 2 | 3 | 4 | |
4 | 1 | 3 | 2 | |
4 | 1 | 2 | 3 | |
3 | 1 | 2 | 4 |
- A Matching: each man is paired with ≤ 1 woman and vice versa
- A Perfect Matching: each man is paired with exactly 1 woman and vice versa
- "perfect" means one-to-one mapping
- A Rogue Couple: a man and a woman who are not matched, but prefer each other to their current partners
- A Stable Matching: A perfect matching without any rogue couples
Solution: Gale-Shapley Algorithm
Proof of Perfection
- Suppose the set of pairs returned by Gale-Shapley algorithm is not perfect
- is a matching, therefore there must be at least one free man
- has proposed to all women (since the algorithm terminated)
- Therefore, each woman must be engaged (since she remains engaged after the first proposal to her)
- Therefore, all men must be engaged, contradicting ⚔️ the assumption that is free
- That matching is perfect since the program terminated QED.
Proof of Stability
- Suppose is not stable i.e. there are two pairs , s.t prefers and prefers
- must have proposed to prior to because at that stage must have rejected ; otherwise she would have been paired with , which would in turn prevent the pairing of in a later iteration
- When rejected , she must have been paired with some man
- Since is paired with at termination, must prefer to or
- This contradicts ⚔️ our conclusion (from instability) that prefers QED.
Observations
- This algorithm computes a matching i.e. each woman gets pair with at most one man and vice versa
- The man's status can alternate between being free and being engaged
- The woman's status remains engaged after the first proposal
- The ranking of a man's partner remains the same or goes down
- The ranking of a woman's partner can never go down
- The number of proposals made after iterations is the best indicator of progress
- The max number of total proposals (or iterations) that can be made is
- Always produces the same matching in which each man is paired with his best, valid partner, but each woman is paired with her worst, valid partner
02 - Analysis of Algorithms
Polynomial Time
- Essentially brute forcing
- e.g. brute force sorting:
- Given numbers, permute them so that they appear in increasing order
- Try all permutations
- For each permutation, check if it is sorted
- Desirable scaling property: when the input size doubles, the algorithm should only slow down by some constant
- An algorithm has polynomial running time if there exists constants such that , the running time is bounded by
- an algorithm is said to be efficient if it has a polynomial running time
Upper and Lower Bounds
- Asymptotic Upper Bound: a function is if there exists constants s.t.
- e.g. is for
- Asymptotic Lower Bound: a function is if there exist constants s.t.
- e.g. is for
In general, we attempt to find a sufficiently large such that our upper and lower bounds are satisfied.
- Asymptotic Tight Bound: a function is if is and is
Transitively:
- if and , then
- if and , then
- if and , then
Additively:
- if and , then
- Similar statements hold for lower and tight bounds
- if is a constant and there are functions:
- if , then
Examples
Reason | ||
---|---|---|
, and we can ignore low order terms | ||
if is an integer constant and | ||
polynomial time | is | |
therefore the base is irrelevant |
- e.g.
- e.g.
03 - Review of Graphs and Priority Queues
Priority Queues: Motivation
Sorting
- Instance: Nonempty list of integers
- Solution: A permutation of such that for all $1 \leq i < n$$
Possible algorithm:
- insert each number into some data structure
- Repeatedly find the smallest number in , output it, and remove it
- To get running time, each "find minimum" step and each remove step must additively take
Priority Queues
- Store a set of elements where each element has a priority value
- smaller key values = higher priorities
- Supported operations:
- find element with smallest key
- remove smallest element
- insert an element
- delete an element
- update the key of an element
- element deletion and key update require knowledge of the position of the element in the priority
- combines benefits of both lists and sorted arrays
- balanced binary tree
- heap order. For every element at a node , the element at 's parent satisfies
- Each node's key is at least as large as its parent's
- storing nodes of the heap in an array:
- Node at index has children at indices and , with a parent at index
- index 1 is the root
- if , where is the current number of elements in the heap, the node at index is a leaf
Heapify-up
Inserting an Element: - insert a new element at index
- Fix heap order using
Heapify-up(H, n+1)
Heapify-up(i)
Proof of Running Time Complexity for - each invocation decreases the second argument by a factor of at least 2
- after invocations, argument is at most
- Therefore which implies that therefore heapify up is
Heapify-down
Deleting an Element: - Suppose has elements
- Delete element moving element at to
- If element at is too small, fix the heap order using
Heapify-up(H, i)
- If element at is too large, fix heap order using
Heapify-down(H, i)
Heapify-down(i)
Proof of Running Time Complexity for - Each invocation increases is second argument by a factor of at least 2
- after invocations arguments must be at least , which implies that
- Therefore running time is
Sorting
- Instance: Nonempty list of integers
- Solution: A permutation of such that for all $1 \leq i < n$$
Final algorithm:
- Insert each number in a priority queue
- Repeatedly find the smallest number in , output it, and delete it from
Thus, each insertion and deletion take for a total running time of
Graphs: Motivation
- Contact tracing hahaaaaa
Taxonomy of a Graph
comprised of vertices and (directed / undirected) edges, they can form face.
Euler Path: Only possible if the number of nodes with odd degree is at most 2
Formally, an Undirected graph where are sets of vertices and edges with
- Elements of are unordered pairs
- is incident on meaning are neighbors of one another
- Exactly one edge between any pair of nodes
- contains no self loops, i.e. no edges of the from
Formally, an directed graph where are sets of vertices and edges with
- Elements of are ordered pairs
- where is the tail of the edge , is the head, and we can say that is directed from to
- A pair of nodes may be connected by two directed edges and
- contains no self loops
A path in an undirected graph is a sequence of nodes s.t. every consecutive pair of nodes is connected by an edge
a path is simple if all its nodes are distinct
a cycle is a path where , the first nodes are distinct and
An undirected graph is connected if, for every pair of nodes , there is a path from to in
The distance between nodes is the minimum number of edges in any path
The connected component of containing is the set of all nodes such that there is an path in
Computing Connected Components
- Rather than computing the connected component of that contains and check if is in that component, we can "explore" starting from , maintaining a set of visited nodes
Breadth First Search
- Explore starting at and going "outward" in all directions, adding nodes one "layer" at a time
- Layer only contains
- Layer contains and all its neighbors, etc. etc.
- Layer contains all nodes that:
- do not belong to an earlier layer
- are connected by an edge to a node in layer
- The shortest path from to each node contains edges
- Claim: For each , layer consists of all nodes exactly at distance from
- A non-tree edge is an edge of that does not belong to the BFS tree
Proof
- There is a path from to if an only iff is a member of some layer
- Let be a node in layer and $$uL_j(u,v)GTuv$
- Notice that is a tree because it is connected and the number of edges in is the number of nodes in all the laters minus one
- is called the BFS Tree
Inductive Proof of BFS Distance Property
- for every , for every node ,
- Basis: ,
- Inductive Hypothesis: Assume the claim is true for every node ,
- Inductive Step: Prove for every node ,
- if is a node in
- Therefore
Depth First Search
- Explore as if it were a maze: start from , traverse first edge out (to node ), traverse first edge out of , . . . , reach a dead-end, backtrack, repeat
Properties of each
- BFS and DFS visit the same set of nodes, but in a different order
Representing Graphs
- A Graph has two input parameters: , with
- Size of graph is defined to be
- Strive for algorithms whose running time is linear in graph size i.e.
- We assume that
- Use an Adjaceny Matrix: boolean matrix, where the entry in row , col is 1 iff the graph contains the edge
- the space used is , which is optimal in the worst case
- can check if there is an edge between nodes , in time
- iterate over all the edges incident on node in time
- Use an Adjaceny List: array , where stores the list of all nodes adjacent to
- an edge appears twice: Adj[v]$
- is the number of neighbors of node
- space used is
- check if there is an adge between nodes in time
- Iterate over all the edges incident on node in time
- Inserting an edge takes time
- Deleting an edge takes time
Operation/Space | Adj. Matrix | Adj. List |
---|---|---|
Is an edge? | time | time |
Iterate over edges incident on node | time | time |
Space used |
04 - Linear-Time Graph Algorithms
Bipartite Graphs
A graph is bipartite if can be partitioned into two subsets such that every edge in has one endpoint in and one in
- and
- Color the nodes in red and the nodes in blue. No edge in connects nodes of the same graph
no cycle with an odd number of nodes is bipartite, similarly all cycles of even length are bipartite
Therefore, if a graph is bipartite, then it cannot contain a cycle of odd length
Algorithm for Testing Bipartite
- Assume is connected, otherwise apply the algorithm to each connected component separately
- Pick an arbitrary node and color it red.
- Color all it's neighbors blue. Color the uncolored neighbors of these nodes red, and so on till all nodes are colored
- Check if every edge has endpoints of different colours
more formally:
- Run BFS on . Maintain an array for the color
- When we add a node to a layer , set to red if is even, blue of odd
- At the end of BFS, scan all the edges to check if there is any edge both of whose endpoints received the same color
Running time is linear proportional to the size of the graph: since we do a constant amount of work per node in addition to the time spent by BFS.
Proof of Correctness of a "two-colorable" algorithm
Need to prove that if the algorithm says is bipartite, then it is actually bipartite AND need to prove that if is not bipartite, can we determine why?
- Let be a graph and let be the layers produced by the BFS, starting at node . Then exactly one of the following statements is true:
- No edge of joins two nodes in the same layer: Bipartite since nodes in the even laters can be colored red and those in odd blue
- There is an edge of that joins two nodes in the same layer: Not Bipartite
05 - Greedy Algorithms
- Greedy algorithms: make the best current choice without looking back. Assume the choices made prior were perfect
Example Problem: Interval Scheduling
At an amusement park, want to compute the largest number of rides you can be on in one day
Input: start and end time of each ride
Constraint: cannot be in two places at one time
Instance: nonempty set of start and finish times of jobs
Solution: The largest subset of mutually compatible jobs
Two jobs are compatible if they do not overlap
Problem models the situation where you have a resource, a set of fixed jobs, and you want to schedule as many jobs as possible
For any input set of jobs, the algorithm must provably compute the largest set of compatible jobs (measured by interval count, not cumulative interval length)
Template for a Greedy Algorithm
- Process jobs in some order. Add next job to the result if it is compatible with the jobs already in the result
- key question: in what order should we process job?
- earliest start time: increasing order of start time
- earliest finish time: increasing order of start time
- shortest interval: increasing order of
- fewest conflicts: increasing order of the number of conflicting jobs
Earliest Finish Time
- the most optimal general solution
Proof of Optimality
- Claim is a compatible set of jobs that is the largest possible in any set of mutually compatible jobs
- Proof by contradiction that there's no "better" solution at each step of the algorithm
- need to define "better", and what a step is in terms of the progress of the algorithm
- order the output in terms of increasing finish time for a measure of progress
- Finishing time of a job selected by must be less than or equal to the finishing time of a job selected by any other algorithm
- Let be an optimal set of jobs. We will show that
- Let be the set of jobs in in order of finishing time
- Let be the set of jobs in in order of
- Claim: for all indices
- Base case: is it possible for finish time of the first job of our algorithm to be later than the opposing job?
- is not possible, only
- Inductive Hypothesis: this is always the case for any generic job index :
- for some
- Inductive Step: show that the same claim holds for the next job:
- for some
- claim :
A complete proof can be found here:
Proof for Optimality of Earliest Finish Time Algorithm for Interval Scheduling
Implementing EFT
- Sort jobs in order of increasing finish time
- Store starting time of jobs in an array
- While
- output job
- Let the finish time of job be
- Iterate over from onwards to find the first index s.t.
- Must be careful to iterate over s.t. we never scan same index more than once
- Running time is since it's dominated by the first sorting step
Scheduling to Minimize Lateness
- Suppose a job has a length and a deadline
- want to schedule all jobs on one resource
- Goal is to assign a starting time to each job such that each job is delayed as little as possible
- A job is delayed if ; the lateness of job is
- the lateness of a schedule is
- the largest of each job's lateness values
Minimizing Lateness
- Instance: Set of lengths of deadlines of jobs
- Solution: Set such that is as small as possible
Template for Greedy Algorithm
Key question: In what order should we schedule the jobs:
- Shortest length: increasing order of length . Ignores deadlines completely, shortest job may have a very late deadline:
1 2 1 10 100 10 - Shortest slack time: Increasing order of . Bad for long jobs with late deadlines. Job with smallest slack may take a long time:
1 2 1 10 2 10 - Earliest Deadline: Increasing order deadline . Correct? Does it make sense to tackle jobs with earliest deadlines first?
Proof of Earliest Deadline Optimality
Inversions
- A schedule has an inversion if a job with a deadline is scheduled before another job with an earlier deadline i.e.
- if two jobs have the same deadline, they cannot cause an inversion
- in jobs, the maximum amount of inversion is
- Claim: if a schedule has and inversion, then there must be a pair of jobs such that is scheduled immediately after and
Proof of Local Inversion
- If we have an inversion between s.t. , then we can find some inverted scheduled between
- This is because: in a list where each element is greater than the last (in terms of deadline), then the list is sorted.
- The contrapositive of this is: if a list is unsorted, then there are two adjacent elements that are unsorted.
Properties of Schedules
- Claim 1: The algorithm produces a schedule with no inversion and no idle time (i.e. jobs are tightly packed)
- Claim 2: All schedules (produced from the same input) with no inversions have the same lateness
- Case 1: All jobs have distinct deadlines. There is a unique schedule with no inversions and no idle time.
- Case 2: Some jobs have the same deadline. Ordering of the jobs does not change the maximum lateness of these jobs.
- Claim 3: There is an optimal schedule with no idle time.
- Claim 4: There is an optimal schedule with no inversions and no idle time.
- Start with an optimal schedule (that may have inversions) and use an exchange argument to convert into a schedule that satisfies Claim 4 and has lateness not larger than .
- If has an inversion, let be consecutive inverted jobs in . After swapping we get a schedule with one less inversion.
- Claim: The lateness of is no larger than the lateness of
- It is sufficient to prove the last item, since after swaps, we obtain a schedule with no inversions whose lateness is no larger than that of
- In , assume each job is scheduled for the interval and has lateness . For , let the lateness of be
- Claim:
- Claim: ,
- Claim: because
- N.B. common mistakes with exchange arguments:
- Wrong: start with algorithm's schedule A and argue it cannot be improved by swapping two jobs
- Correct: Start with an arbitrary schedule O (which can be optimal) and argue that O can be converted into a schedule that is essentially the same as A without increasing lateness
- Wrong: Swap two jobs that are not neighboring in . Pitfall is that the completion time of all intervening jobs then changes
- Correct: Show that an inversion exists between two neighboring jobs and swap them
- Claim 5: The greedy algorithm produces an optimal schedule, follows from 1, 2, 4
Summary
- Greedy algorithms make local decisions
- Three strategies:
- Greedy algorithm stays ahead - Show that after each step in the greedy algorithm, its solution is at least as good as that produced by any other algorithm
- Structural bound - First, discover a property that must be satisfied by every possible solution. Then show that the (greedy) algorithm produces a solution with this property
- Exchange argument - Transform the optimal solution in steps into the solution by the greedy algorithm without worsening the quality of the optimal solution
06 - Greedy Graph Algorithms
The Shortest Path Problem
- is a connected, directed graph. Each edge has a length
- length of a path us the sum of the lengths of the edges in
- Goal: compute the shortest path from a specified start node to every other node in the graph
- Instace: A directed graph , a function and a node
- Solution: A set of paths, where is the shortest path in from to
Generalizing BFS
- If all edges have the same wight, or distance, BFS would work, processing nodes in order of distance.
- What if the graph has integer edge weights, can we make the graph unweighted?
- yes, placing dummy edges and nodes to pad out lengths > 1 at the expense of memory and running time
- Edge weight of gets nodes
- Size of the graph (and therefore runtime) becomes . Pseudo-polynomial time depending on input values
Dijkstra's Algorithm
- Famous for pointing out the harm of the
goto
command, in doing so developed the shortest path algorithm - Like BFS: explore nodes in non-increasing order of distance . Once a node is explored, its distance is fixed
- Unlike BFS: Layers are not uniform, edges are explored by evaluating candidates by edge wight
- For each unexplored node, determine "best" preceding explored node. Record shortest path length only through explored nodes
- Like BFS: Record previous node in path, and build a tree.
Formally:
- Maintain a set of explored nodes
- For each node , compute , which (we will prove, invariant) is the length of the shortest path from to
- For each node , maintain a value , which is the length of the shortest path from to using only the nodes in and itself
- Greedily add a node to that has the smallest value of
What does mean?
- Run over all unexplored nodes
- examine all values for each node
- Return the argument (i.e. the node) that has the smallest value of
To compute the shorts paths: when adding a node to , store the predecessor that minimizes
Proof of Correctness
Let be the path computed by the algorithm for an arbitrary node
Claim: is the shortest path from to
Prove by induction on the size of
- Base case: . The only node in is
- Inductive Hypothesis: for some . The algorithm has computed for every node . Strong induction.
- Inductive step: because we add the node to . Could the be a shorter path from to ? We must prove this is not the case.
- poll: must contain an edge from x to y where x is explore (in S) and y is unexplored (in V - S)
- poll: The node v in P' must be explored (in S)
Locate key nodes on
- Break into sub-paths from to , to , to - use to denote the lengths of the sub-paths in - - - -
Observations about Dijkstra's Algorithm
- As described, it cannot handle negative edge lengths
- Union of shortest paths output by Dijkstra's forms a tree: why?
- Union of the shortest paths from a fixed source forms a tree; paths not necessarily computed by computed by Dijkstra's
Running time of Dijkstra's
- has nodes and edges, so their are iterations on the while loops
- In each iteration, for each node , compute which is proportional the the number of edges incident on
- Running time per iteration is , since the algorithm processes each edge in the graph exactly once (when computing )
- Therefore, the overall running time is
Optimizing our Algorithm
- Observation, if we add to , changes only if is an edge in
- Idea: For each node , store the current value of . Upon adding a node to , update only for neighbors of
- How do we efficiently compute
- Priority Queue!
- For each node , store the pair in a priority queue with as the key
- Determine the next node to add to using
- After adding to , for each node such that there is an edge from to , check if should be updated i.e. if there is a shortest path from to via
- in line 8, if is not in , simply insert it
New Runtime
- happens times
- For every node , the running time of step 5 , the number of outgoing neighbors of :
- is invoked at most once for each edge, times, and is an operation
- So, the total runtime is
Network Design
- want to connect a set of nodes using a set of edges with certain properties
- Input is usually a graph, and the desired network (output) should use a subset of edges in the graph
- Example: connect all nodes using a cycle of shortest total length. This problem is the NP-complete traveling salesman problem
Minimum Spanning Tree (MST)
- Given an undirected graph with a cost associated with each edge .
- Find a subset of edges such that the graph is connected and the cost is as small as possible
- Instance: An undirected graph and a function
- Solution: A set of edges such that is connected and the cost is as small as possible
- Claim: if is a minimum-cost solution to this problem, then is a tree
- A subset is a spanning tree of if is a tree
Characterizing MSTs
- Does the edge of smallest cost belong to an MST? Yes
- Wrong proof: Because Kruskal's algorithm adds it.
- Right proof: tbd
- Which edges must belong to an MST?
- What happens when we delete an edge from an MST?
- MST breaks up into sub-trees
- Which edge should we add to join them?
- Which edges cannot belong to an MST?
- What happens when we add an edge to an MST?
- We obtain a cycle
- Which edge in the cycle can we be sure does not belong to an MST
Greedy Algorithm for the MST Problem
- Template: process edges in some order. Add an edge to if tree property is not violated.
- increasing cost order: Process edges in increasing order of cost. Discard an edge if it creates a cycle – Kruskal's
- Dijkstra-like: Start from a node and grow outward from : add the node that can attached most cheaply to current tree – Prim's
- Decreasing cost order: Delete edges in order of decreasing cost as long as graph remains connected – Reverse-Delete
- each of these works
- Simplifying assumption: all edge costs are distinct
Graph Cuts
- a cut in a graph is a set of edges whose removal disconnects the graph (into two or more connected components)
- Every set ( cannot be empty or the entire set ) has a corresponding cut: cut() is the set of edges (v,w) such that
- cut() is a "cut" because deleting the edges in cut() disconnects from
- Claim: for every , every MST contains the cheapest edge in cut)
- will have to proof by contradiction using exchange argument
Proof of Cut Property of MSTs
- Negation of the desired property: There is a set and an MST such that does not contain the cheapest edge in cut()
- Proof strategy: If does not contain , show that there is a tree with a smaller cost than that contains .
- Wrong proof:
- Since is spanning, it must contain some edge e.g. in cut($S)
- has smaller cost than but may not be a spanning tree
- Correct proof:
- Add to forming a cycle
- This cycle must contain an edge in cut()
- has smaller cost than and is a spanning tree
Prim's Algorithm
- Maintain a tree (S, T), i.e., a set of nodes and a set of edges, which we will show will always be a tree
- Start with an arbitrary node
- Step 3 is the cheapest edge in cut(S) for the currently explored set S
- In other words, each step in Prim's algorithm computes and adds the cheapest edge in the current value of cut()
Optimality of Prim's
- Claim: Prim's algorithm outputs an MST
- Prove that every edge inserted satisfies the cut property (true by construction, in each iteration is necessarily the cheapest edge in cut() for the current value of )
- Prove that the graph constructed is a spanning tree
- Why are there no cycles in
- Why is a spanning tree (edges in connect all nodes in ) - Because is connected, if there were an unconnected node at the end, then Prim's would not have terminated
Final version of Prim's Algorithm
- is a priority queue
- Each element in is a triple, the node, its attachment cost, and its predecessor in the MST
- In step 8, if is not already in , simply insert (x, a(x), v) into
- Total of and operations, yielding a running time of
- running time of step 5 is proportional to the degree of which is proportional to the number of edges in the graph
Kruskal's Algorithm
- Start with an empty set of edges
- Process edges in in increasing order of cost
- Add the next edge to only if adding does not create a cycle. Discard otherwise
- Note: at any iteration, may contain several connected components and each node in is in some component
- Claim: Kruskal's algorithm outputs an MST
- For every edge added, demonstrate the existence of a set (and ) such that and satisfy the cut property, i.e.e, the cheapest edge in
- If , let be the set of nodes connected to in the current graph
- Why is the cheapest edge in cut() - because we process them in increasing order of cost
- Prove that the algorithm computes a spanning tree
- contains no cycles by construction
- If is not connected, then there exists a subset of nodes not connected to . What is the contradiction?
- For every edge added, demonstrate the existence of a set (and ) such that and satisfy the cut property, i.e.e, the cheapest edge in
Implementing Kruskal's Algorithm
- start with an empty set of edges
- Process edges in in increasing order of cost
- Add the next edge to only if adding does not create a cycle
- Sorting edges takes time
- Key question: "Does adding to create a cycle?
- Maintain set of connected components of
- : return the name of the connected component of that belongs to
- : merge connected components A, B
Analysing Kruskal's Algorithm
- How many invocations does Kruskal's need?
- How many invocations?
- Two implementations of :
- Each take , invocations of takes time in total –
- Each take , each invocation of takes –
- In general , but in either case, the total running time is since we have to spend time sorting the edges by increasing cost, regardless of the underlying implementation of the data structure
Comments on Union-Find and MST
- useful to maintain connected components of a graph as edges are added to the graph
- Data structure does not support edge deletion efficiently
- Current best algorithm for MST runs in time (Chazelle 2000) where is a function of and randomized time
- Let the number of times you take before you reach 1
- e.g. ,
- Holy grail: deterministic algorithm for MST
Cycle Property
- When can we be sure that an edge cannot be in any MST
- Let be any cycle in and let be the most expensive edge in
- Claim: does not belong to any MST of G
- Proof: exchange argument.
- If a supposed MST contains , show that there is a tree with smaller cost than that does not contain
Reverse-Delete Algorithm
¯\(ツ)/¯
Observations about MST algorithms
- Any algorithm that constructs a spanning tree by including the Cut and Cycle properties (include edges that satisfy the cut P, delete edges that satisfy the cycle property) will be an MST
07 - Applications of Minimum Spanning Trees
Minimum Bottleneck Spanning Tree (MBST)
- MST minimizes the total cost of the spanning network
- Consider another network design criterion
- build a network connecting all cities in mountainous region, but ensure the highest elevation is as low as possible
- total road length is not a criterion
- Idea: compute an MST in which the edge with the highest cost is as cheap as possible
- In an undirected graph , let be a spanning tree. The bottleneck edge in is the edge with the largest cost in
- Instance: An an undirected graph such that is a spanning tree
- Solution: A Set of edges such that is a spanning tree and there is no spanning tree in with a cheaper bottleneck
Is every MST and MBST, or vice versa?
- If a tree is an MBST, it might not be an MST
- If a tree is an MST, it will be an MBST
Proof:
- Let be the MST, and let be a spanning tree with a cheaper bottleneck edge.
- Let be the bottleneck edge in
- Every edge in has lower cost than
- Adding to creates a cycle consisting only of edges, where is the costliest edge in the cycle
- Since is the costliest edge in this cycle, by the cycle property, cannot belong to any MST, which contradicts the fact that is an MST
Motivation for Clustering
- Given a set of objects and distances between them
- objects can be anything
- Distance function: increase distance corresponds to dissimilarity
- Goal: group objects into clusters, where each cluster is a group of similar objects
Formalizing the Clustering Problem
- Let be the set of objects labels
- For every pair , we have a distance
- We require that , , ,
- Given a positive integer , a k-clustering of is a partition of into non-empty subsets or clusters
- that spacing of a clustering is the smallest distance between objects in 2 different subsets:
- spacing is the minimum of distance between objects in two different subsets
minimum = inifnity
for every cluster C_i
for every cluster C_j ≠ i
for every point p in C_i
for every point q in C_j
if d(p,q) < minimum
minimum = d(p,q)
return minimum
- Clustering of Maximum Spacing
- Instance: a Set of objects, a distance function
- Solution: A k-clustering of whose spacing is the largest over all possible k-clusterings
- on clusters and then on points in disparate cluster
Algorithm for Max Spacing
- intuition: greedily cluster objects in increasing order of distance
- Let be the set of clusters, with each object in in its own cluster
- Process pairs of objects in increasing order of distance
- Let be the next pair with and
- If add a new cluster to , delete from
- Stop when there are cluster in
- Same as Kruskal's algorithm, but do not add the last edges in MST
- Given a clustering , what is spacing()?
- The length of the next edge that would be added - the cost of the st most expensive edge in the MST. Let this cost be
Proof of optimal computing
- Let be any other cluster (with clusters).
- We will prove that spacing()
- There must be two objects in the same cluster but in different clusters in : spacing()
- Suppose and in
- All edges in the path connecting in the MST have lengths
- In particular, there is an object and an object s.t. and are adjacent in
- spacing()
Explanation
- is the name we give to the variable denoting the spacing produced by our algorithm$
- The above proof shows that any other clustering will have a smaller spacing
08 - Divide and Conquer Algorithms
Mergesort
- Instance: nonempty list integers
- Solution: A permutation of such that for all
- Mergesort is a divide and conquer algorithm for sorting
- Partition into two lists of sizes
- Recursively sort ,
- Merge the sorted lists into a sorted list
Merging Two Sorted Lists
- Maintain a current pointer for each list
- initialize each pointed to the front of the list
- While both lists are non-empty:
- let be the elements pointed to by each pointer
- append the smaller of the two to the output list
- advance the current pointer in the list that the smaller element belonged to
- append the rest of the non-empty list to the output
- Running time of this algorithm is ,
Analysing Mergesort
- Running time for = running time for running time for time to split the input into two lists time to merge two sorted lists
- what is this in the worst case?
- worst case running time for time to split input into two lists + time to merge two sorted lists
- This sucks to read, need a shorthand. Let's assume is a power of 2
- Let be the worst-case running time for elements,
- Worst-case running time:
- , is some constant time to split the list
- Can assume for problem sets
Analysing Mergesort in the Worst Case
- Partition into two lists and of size respectively
- Recursively sort and
- Merge the sorted lists into a single sorted list
- Worst case running time for elements ≤
- worst case running time for +
- worst case running time for +
- time to split the input into two lists +
- time to merge two sorted lists
- Assuming is a power of 2:
- Three basic ways of solving this recurrence relation:
- "Unrolling" the recurrence
- Guess a solution and substitute into recurrence to check
- Guess a solution in form and substitute into recurrence to determine the constants
Unrolling
- Input to each sub problem on level has size
- Recursion tree has levels
- Number of sub-problems on level has size
- Total work done at each level is
- Running time of the algorithm is
Substituting a Solution into the Recurrence
Guess that the solution is (log base 2)
Use induction to check if the solution satisfies the recurrence relation
Base case: . Is ? yes.
(strong) Inductive Hypothesis: must include
- Assume , for all , therefore
Inductive Step: Prove
Why is a "loose" bound?
Why doesn't an attempt to prove