Analogies for learning algorithms
I love analogies that involve food.
November 30, 2022
In this post, I'll give some analogies about learning and teaching. For the sake of concreteness, I'll stick to algorithms, the topic I know best, in the context of an undergraduate computer science (CS) curriculum. I'll let you think about how these analogies apply to other topics.
Why learn algorithms? I've written about this before, but I'll reiterate the problem here. In many CS curricula, algorithms is one of the few courses that doesn't require writing code. This leads some students to think that learning algorithms is a waste of time and energy. To make matters worse (for these students), the algorithms course is often pretty challenging.
So why are CS students required to learn algorithms? First, let's remember that CS is not software engineering. If you're studying CS, then you really should learn some algorithms, because according to Wikipedia, "Algorithms and data structures are central to computer science." Of course I'm biased, but I'd say that the algorithms is to CS as flour is to pasta.
But even if you're not pursuing a CS degree, I still think you should learn some algorithms because it's good for your brain. Why do football players bench press? After all, in the game of football, players don't get on their backs and push a weighted bar off their chests. The reason they bench, of course, is that benching increases their physical strength, which anyone who has watched a minute of football can see is useful. Similarly, learning algorithms develops mental strength, which is useful for solving problems in computer programming and beyond.
Fine, I'll learn. But why should I take a course? It is certainly true that one can learn algorithms without taking an entire college course. In theory, one could also become an elite athlete without a gym membership or a coach. Just go online, find some exercises that you can do in your living room, and get at it. That might work, but wouldn't it be more effective (and enjoyable) to have the resources of a gym and the guidance of a coach? (I again realize that I am biased. I'll stop pointing that out now.)
Taking a class is an opportunity to learn things the "right" way. I am certainly not the Bob Bowman of algorithms. But at the same time, you're probably not the Michael Phelps of algorithms. So if you want to get fitter (and you've never taken this class before), I can probably help you out. I can show you how to use the equipment, provide workout schedules, measure your progress, establish goals, and help you achieve them. In exchange, I'll trust that you'll make an honest effort.
Great. What will I be learning? We'll learn how to solve problems using algorithms. Unfortunately, every problem requires its own algorithm, and these algorithms often look very different from each other. Even algorithms that look similar might have critical differences in their details. So trying to solve a problem you've never seen can be a daunting task.
Fortunately, the set of all algorithms (or at least the ones we learn in the beginning) can be roughly organized by their "main idea" or technique. Let's switch from exercise analogies back to food analogies: imagine the set of all problems as the set of all dishes. There's no recipe that produces every dish. Similarly, there's no algorithm that solves every problem. But in cooking, there are techniques such as frying, roasting, and steaming. Mastering each technique enables us to create certain types of dishes. Similarly, there are algorithmic techniques such as divide and conquer, dynamic programming, and linear programming. Mastering each technique enables us to solve certain types of problems.
As we gain experience, we'll hone our intuition for solving computational problems. We'll be able to cook without following a recipe. We'll say things like, "I think dynamic programming should work here," and we'll be correct more often than not. Ideally, we'll reach the "post-rigorous" stage of mathematical education, in which we reason about things at a "big picture" level but can also formalize our thoughts as necessary. Terence Tao's blog post is about math, but I don't think it's a big stretch to extend the three stages he describes to algorithms: in the "pre-rigorous" stage we fumble around with our intuition, in the "rigorous" stage we write code, and in the "post-rigorous" stage we write pseudocode and proofs.
Unfortunately, this is all easier said than done, and there are limitations. Cooking a corn dog is not the same as preparing Michelin-starred tempura, even though both involve frying. Similarly, finding the sum of an array is not the same as finding a longest increasing subsequence, even though both (can) involve dynamic programming. Moreover, going from "I can solve a problem using dynamic programming" to "I can intuitively recognize when a problem can, or cannot, be solved using dynamic programming" is also a bit of a leap. But this is what makes cooking and algorithms interesting fields. There's always room for improvement, and it's satisfying to make progress.
Okay, I am totally convinced that I should learn algorithms, and I can't wait to embark on this exciting journey. How do I improve? This question is simultaneously trivial and difficult to answer. Even if I were Bob Bowman and you were Michael Phelps, how do you improve? Practice, of course. If you don't get in the water and swim, then whether or not you have access to the best resources/coach doesn't matter. No pain, no gain.
On the other hand, the term "practice" is pretty vague. At the very least, we should try to do something more deliberate, like deliberate practice. But what does that even mean in the context of algorithms? I won't get into that here; I'll just plug a previous post again. Good luck!