CS 351: Analysis of Algorithms
What We’ll Discuss Today
Alice’s ratings:
Avengers: 5 stars
Romantic Comedy: 2 stars
Movie features:
Titanic has:
- Action level: 1
- Romance level: 5
Prediction formula: Alice’s predicted rating = (5 × 1) + (2 × 5) = 15
In general: Each cell in the result = Row from first grid × Column from second grid
The Computer’s Method:
Checkpoint Question 1: If we have 1000 users, 1000 movies, and 100 features, how many steps does this take?
User Ratings Grid:
Avengers Titanic Comedy1
Alice 5 2 4
Bob 1 5 3
Carol 4 1 5
Movie Features Grid:
Action Romance
Avengers 5 1
Titanic 1 5
Comedy1 2 3
Reality Check: How long does the basic method take?
Grid Size | Real-World Example | Time with Basic Method |
---|---|---|
100×100 | Small mobile game | 0.01 seconds |
1,000×1,000 | Netflix for small city | 17 minutes |
10,000×10,000 | Netflix nationwide | 11.6 DAYS |
The Question: Can we do better than the basic approach?
Big Idea: “Divide and Conquer” - Break big problems into smaller pieces
Real-World Analogy: Like organizing a huge library:
For Matrix Math:
The Idea: Treat blocks of numbers like individual numbers
Example: Split a 4×4 grid into four 2×2 blocks
Original grids: Split into blocks:
[a b c d] [A B] where A = [a b]
[e f g h] → [C D] B = [c d] etc.
[i j k l]
[m n o p]
Block Multiplication Rule: Same pattern as regular multiplication!
[A B] × [E F] = [A×E + B×G A×F + B×H]
[C D] [G H] [C×E + D×G C×F + D×H]
The Algorithm:
Problem: This needs 8 “recursive calls” - is that actually better?
The Question: Is our block method actually faster?
Let’s Think About It:
The Pattern:
Work to solve size n = 8 × (work to solve size n/2) + easy combining work
In Math Notation:
Need a Tool: How do we solve this kind of equation to find out if we’re actually faster?
Hypothetical Scenario 😶🌫️
What if we had a systematic tool to analyze “divide and conquer” algorithms and told us exactly how fast (or slow) our approach is?
The Tool: For any “divide and conquer” algorithm, answer these questions:
The Magic Formula: Based on your answers, the tool predicts your algorithm’s speed!
The Three Possible Outcomes
Which case applies? Compare a with \(b^{d}\)
Problem: Sort 1000 photos by date
Divide-and-Conquer Approach:
Recipe: \(a = 2,\; b = 2,\; d = 1\)
Analysis: \(a = 2,\; b^{d} = 2^{1} = 2\), so \(a = b^{d}\) → Case 1
Result: \(\text{Time} = n \times \log(n)\) — much better than \(n^{2}\) naive sorting!
Problem: Find “pizza” in a sorted list of 1 billion web pages
Binary Search Approach:
Recipe: \(a = 1,\; b = 2,\; d = 0\)
Analysis: \(a = 1,\; b^{d} = 2^{0} = 1\), so \(a = b^{d}\) → Case 1
Result: \(\text{Time} = \log(n)\) — find anything in \(\sim30\) steps!
Problem: Netflix recommendation calculation
Our Block Approach:
Recipe: \(a = 8,\; b = 2,\; d = 2\)
Analysis: \(a = 8,\; b^{d} = 2^{2} = 4\), so \(a > b^{d}\) → Case 3
Result: \(\text{Time} = n^{3}\) — same as the basic method!? 😞
The Problem: Our block method didn’t help because we needed 8 calculations (a = 8)
The Big Question: What if we could do it with only 7 calculations instead of 8?
Seems Impossible!
To multiply blocks:
[A B] × [E F] = [? ?]
[C D] [G H] [? ?]
We need: AE, BG, AF, BH, CE, DG, CF, DH
That’s 8 different values - how can 7 calculations possibly be enough?
The Genius Insight (1969):
A mathematician named Strassen found a way!
The Secret: Don’t calculate those 8 values directly. Instead:
Why This Matters:
That one less calculation breaks the n³ barrier for the first time in history! This is Strassen’s breakthrough.
The Challenge: We need these 8 block multiplications:
AE, BG, AF, BH, CE, DG, CF, DH
Strassen’s Secret Recipe: Instead, calculate these 7 special combinations:
Step | What to Calculate | Why This Helps |
---|---|---|
1 | A × (F - H) | Captures A×F relationship |
2 | (A + B) × H | Captures both A×H and B×H |
3 | (C + D) × E | Captures both C×E and D×E |
4 | D × (G - E) | Captures D×G relationship |
5 | (A + D) × (E + H) | Captures diagonal elements |
6 | (B - D) × (G + H) | Balances the equations |
7 | (A - C) × (E + F) | Completes the system |
The Reconstruction Magic:
These 7 values contain enough information to figure out all 8 original values through addition and subtraction!
Performance Impact:
Real-World Impact: Netflix calculations that took 1 hour now take 25 minutes!
Applying Our Algorithm Analyzer to Strassen:
Strassen’s Recipe: \(T(n) = 7T\!\left(\frac{n}{2}\right) + \text{(combining work)}\)
The Numbers:
Algorithm Analyzer Says: \(a = 7 \quad\text{vs}\quad b^{d} = 4\)
Since \(7 > 4\), we have Case 3 (Bottom-Heavy)
Final Result: Time = \(n^{\log_{2}7} = n^{2.807}\)
Historic Achievement
First algorithm EVER to beat the “obvious” n³ approach for matrix multiplication!
The Impact in Real Numbers:
Problem Size | Old Method | Strassen’s Method | Improvement |
---|---|---|---|
1,000×1,000 Netflix | 17 minutes | 4.2 minutes | 4× faster |
10,000×10,000 Enterprise | 11.6 days | 1.9 days | 6× faster |
Why One Less Calculation Matters So Much: The savings compound at every level of recursion!
Checkpoint Question 3: Why does reducing from 8 to 7 calculations have such a dramatic effect?
Problem: Multiply two very large numbers (like in cryptography)
Smart Algorithm (Karatsuba): Instead of the grade-school method
- Split big numbers in half → 3 calculations instead of 4
- Each calculation is on half-sized numbers → \(b = 2\)
- Combining results takes linear time → \(d = 1\)
Recipe: \(a = 3,\; b = 2,\; d = 1 \rightarrow 3 > 2^{1}\) → Case 3
Result: \(n^{1.59}\) instead of \(n^{2}\) — saves millions in processing costs!
Problem: Process all friendships in Facebook’s social graph
Tree Processing Algorithm:
- Visit each person exactly once → 2 recursive calls
- Each call processes half the network → \(b = 2\)
- Minimal work per person → \(d = 0\)
Recipe: \(a = 2,\; b = 2,\; d = 0 \rightarrow 2 > 1\) → Case 3
Result: Exactly \(n\) steps — optimal since you must visit everyone!
Problem: Find a specific post in your Instagram feed (sorted by time)
Enhanced Binary Search:
- One recursive search → \(a = 1\)
- Search half the remaining posts → \(b = 2\)
- Some extra processing per step → \(d = 1\)
Recipe: \(a = 1,\; b = 2,\; d = 1 \rightarrow 1 < 2\) → Case 2
Result: Linear time — the search overhead dominates!
Instructions: Work in pairs. For each real-world scenario, figure out a, b, d and predict the performance:
Scenario 1: Photo Editing App
You’re building Instagram filters. To blur a photo:
Scenario 2: Video Game Graphics
Rendering 3D objects by breaking them down:
Scenario 3: Spotify Recommendations
Finding similar songs in a music database:
Your Analysis*
For each scenario, determine:
The Tool Has Limits: Our Algorithm Analyzer only works for certain types of problems
Your algorithm must:
- Break problems into equal-sized pieces
- Always make the same number of recursive calls
- Do roughly the same amount of extra work each time
Example 1: Cleaning Your Room
“Clean the biggest mess first, then clean everything else”
- Two subproblems but they’re different sizes
- Our analyzer assumes equal sizes
Example 2: Planning a Trip
“Visit \(n\) cities, planning gets harder as trip gets longer”
- The planning work depends on trip length
- Our analyzer assumes constant extra work
Example 3: Processing Email
“Handle today’s email, then yesterday’s, then day before…”
- Reduces by 1 email per step, not by a constant factor
- Our analyzer assumes you divide by a fixed number
The Theory vs Reality Problem:
Strassen’s Advantages:
- Faster for huge problems (like Netflix’s full user base)
- Shows that “impossible” improvements are possible
- Inspired decades of further research
Strassen’s Disadvantages:
- Complex to implement — easy to make bugs
- Uses more memory — lots of temporary storage
- Only faster for big problems — small problems run slower
- Numerical errors — subtractions can amplify rounding mistakes
Hybrid Approaches:
- Small problems: Use simple method (faster due to less overhead)
- Large problems: Switch to Strassen-style methods
- Find the sweet spot: Experiment to find best crossover point
Modern Examples:
- Video games: Simple method for small 3D objects, advanced for complex scenes
- Netflix: Simple method for individual recommendations, advanced for batch processing
- Phone cameras: Simple method for preview, advanced for final photo processing
What it’s good for:
- Quick comparisons between algorithm approaches
- Understanding why some methods are better
- Predicting which approach will win for large problems
What it misses:
- Real hardware effects (cache, parallel processing)
- Implementation complexity and bugs
- Small problem performance
The Matrix Multiplication Story
The Problem: Netflix, video games, and AI need to multiply huge grids of numbers fast
First Try: Use the obvious method → \(n^{3}\) steps (too slow for big problems)
Second Try: Divide and conquer → still \(n^{3}\) steps (divide-and-conquer alone isn’t magic)
The Breakthrough: Strassen’s 1969 discovery → reduce 8 calculations to 7 → \(n^{2.807}\) steps
The Lesson: Sometimes “impossible” improvements are possible with creative thinking
The Algorithm Analyzer Tool (Master Method)
What it does: Predicts performance of any “divide and conquer” algorithm
How to use it:
1. Count recursive calls (\(a\))
2. See how much smaller subproblems get (\(b\))
3. Measure extra work (\(d\))
4. Compare \(a\) with \(b^{d}\) to get your answer
Three outcomes: Balanced (Case 1), Top-heavy (Case 2), Bottom-heavy (Case 3)
When it helps: Quick analysis, comparing approaches, understanding why algorithms work
Question 1:
Imagine someone found an even better way to do Strassen’s algorithm with only 6 recursive calls instead of 7.
What would happen to the performance?
- Hint: \(a = 6,\; b = 2,\; d = 2 \;\rightarrow\; n^{\log_{2}6} \approx n^{2.585}\) — even faster than \(n^{2.807}\).
Question 2:
Why didn’t our first “divide and conquer” attempt improve over the basic method,
even though breaking problems into pieces usually helps?
- Hint: Splitting into equal halves but still doing 8 sub-multiplications → \(a = 8,\; b = 2,\; d = 2\) → still \(n^{3}\),
so overhead wasn’t reduced.
Question 3:
You’re building a mobile app.
When would you choose the simple \(n^{3}\) method over Strassen’s faster \(n^{2.807}\) method?
- Hint: For small matrices or memory-limited devices — Strassen’s overhead and extra memory can make it slower or impractical.
Huge improvement!
Recipe: \(a = 6,\; b = 2,\; d = 2 \;\rightarrow\; 6 > 4\) Case 3 → \(n^{2.585}\) time (even faster!)
Too many recursive calls!
We created 8 subproblems, which overwhelmed any benefit from making them smaller.
For small problems (simpler code, fewer bugs), when battery life matters (simpler operations), or when precision is critical (fewer rounding errors).
Questions about anything we covered?
What’s Next?