Getting Started
Imagine you have two different sets of driving directions to the same destination. One route is shorter in distance but has many stoplights, while the other is longer but uses a high-speed freeway. Which route is "better"? The answer depends on whether you want to minimize distance, time, or fuel. In computer science, we face a similar challenge: there are often many ways to solve a single problem, and we need a formal way to measure and compare these solutions to find the most effective one.
What You Should Be Able to Do
Explain the difference between a general problem and a specific instance of that problem.
Compare two algorithms that solve the same problem to determine which is more efficient.
Explain the difference between algorithms that run in a reasonable amount of time and those that do not.
Describe how a heuristic can be used to find an approximate solution to a complex problem.
Identify the key characteristics of a problem that may be undecidable by any algorithm.
Key Concepts & Application
The Core Idea
An algorithm is a finite set of instructions that accomplishes a task. While many different algorithms can solve the same problem correctly, they are not all created equal. Some are fast and use minimal memory, while others are slow and resource-intensive, especially as the amount of data they have to process grows.
Efficiency is the measure of an algorithm's use of computational resources, primarily time (the number of steps it takes) and space (the amount of memory it requires). In this context, we are most often concerned with time efficiency. An efficient algorithm solves a problem quickly and is scalable, meaning it can handle large inputs without becoming unacceptably slow. An inefficient algorithm might work perfectly for small inputs but become completely impractical as the input size increases.
Logic & Application
To analyze efficiency, we must first distinguish between a problem and its specific inputs.
A problem is a general description of a task that can be solved with an algorithm (e.g., "find a name in a list").
An instance of a problem is one specific case, with specific inputs (e.g., "find the name 'Maria' in the list
[Ken, Maria, David]).
Let's compare two algorithms for finding a specific value in a list.
Annotated Pseudocode Examples
Algorithm 1: Linear Search
This algorithm checks every item in a list, one by one, until it finds the target value or reaches the end.
PROCEDURE LinearSearch (list, target)
{
FOR EACH item IN list
{
// This comparison is one step.
IF (item = target)
{
RETURN true // Found it!
}
}
RETURN false // Reached the end without finding it.
}
- Analysis: In the worst-case scenario (the
targetis the last item or not in the list at all), this algorithm must perform one comparison for every single item. If the list hasnitems, it takes approximatelynsteps.
Algorithm 2: A Less Efficient Search
This algorithm searches for a value in a two-dimensional grid (a list of lists). To find a single value, it must check every column in every row.
PROCEDURE GridSearch (grid, target)
{
FOR EACH row IN grid
{
FOR EACH item IN row
{
// This comparison is one step.
IF (item = target)
{
RETURN true // Found it!
}
}
}
RETURN false // Reached the end without finding it.
}
- Analysis: If the grid has
nrows andncolumns, this algorithm has nested loops. For each of thenrows, it must performnsteps. The total number of steps in the worst case is approximatelyn * n, orn².
Tracing & Analysis
The difference in efficiency becomes clear as the input size (n) grows.
Input Size (n) | Algorithm 1 (Linear Search) Steps | Algorithm 2 (Grid Search) Steps |
|---|---|---|
| 10 | ~10 | ~100 |
| 100 | ~100 | ~10,000 |
| 1,000 | ~1,000 | ~1,000,000 |
As the table shows, GridSearch becomes impractical much faster than LinearSearch. This leads to a crucial classification of algorithmic efficiency.
Reasonable Time: Algorithms like
LinearSearch, whose number of steps is proportional to the input size raised to a constant power (liken,n², orn³), are said to run in a polynomial or reasonable time. They are practical for solving problems, even with large inputs.Unreasonable Time: Algorithms whose number of steps grows exponentially (like
2ⁿ) or factorially (n!) are said to run in an unreasonable time. While they may work for very small inputs, they quickly become too slow to be useful as the input size increases. A supercomputer would not be able to solve a large instance of an unreasonable time problem.
Heuristics and Unsolvable Problems
What happens when the only known algorithm for a problem runs in unreasonable time? For these optimization problems (problems that seek the best solution) or decision problems (problems with a yes/no answer), we can use a heuristic.
A heuristic is an algorithmic approach that provides a "good enough" solution when an optimal or exact solution is impractical to find. For example, a GPS navigation app uses a heuristic to find a fast route. It doesn't calculate every possible path (which would take too long); instead, it uses a clever approximation to find a route that is likely very close to the best one.
Finally, some problems are simply unsolvable. An undecidable problem is a decision problem for which no algorithm can ever be constructed that will always provide a correct yes-or-no answer for all inputs.
Core Concepts & Terminology
Algorithm: A finite, sequential set of instructions used to accomplish a specific task.
Efficiency: A measure of the amount of computing resources, primarily time (steps) and memory (space), that an algorithm requires.
Problem: A general description of a task, such as "sort a list."
Instance: A specific input for a given problem, such as "sort the list
[5, 2, 8]."Decision Problem: A problem that has a yes-or-no answer for all inputs (e.g., "Is the number
xin this list?").Optimization Problem: A problem with the goal of finding the best solution from among many possible solutions (e.g., "What is the shortest path between two cities?").
Reasonable Time: An algorithm is said to run in a reasonable time if its efficiency is a polynomial function of the input size (e.g.,
n,n²). It remains practical for large inputs.Unreasonable Time: An algorithm is said to run in an unreasonable time if its efficiency is an exponential or factorial function of the input size (e.g.,
2ⁿ,n!). It quickly becomes impractical even for moderately sized inputs.Heuristic: An approach to a problem that produces a solution that is not guaranteed to be optimal but is "good enough" for a particular purpose, especially when an exact solution is too inefficient to find.
Decidable Problem: A decision problem for which an algorithm can be written that will always produce a correct answer.
Undecidable Problem: A decision problem for which no algorithm can be constructed that is always capable of providing a correct yes-or-no answer.
Core Skill Check
Efficiency Analysis: Approximately how many times will the
DISPLAYcommand run if the inputnis 10?i <- 1 REPEAT n TIMES { j <- 1 REPEAT n TIMES { DISPLAY(i * j) j <- j + 1 } i <- i + 1 }Comparison: An algorithm that takes
n³steps is considered to run in a reasonable time. An algorithm that takes3ⁿsteps is considered to run in an unreasonable time. Which will be faster for an input size ofn = 5?Application: Describe a real-world scenario where a heuristic is used because finding the perfect, optimal solution would take too long.
Common Misconceptions & Clarifications
"A faster computer can solve any problem quickly."
- Clarification: While a faster computer helps, an algorithm with unreasonable time complexity will become impractically slow on any machine as the input size grows. The underlying logic of the algorithm, not the hardware speed, is the limiting factor.
"The algorithm with the fewest lines of code is the most efficient."
- Clarification: The length of the code has no direct relationship to its computational efficiency. A short, three-line algorithm with nested loops can be far less efficient than a longer, 20-line algorithm that processes data more cleverly.
"A heuristic is just a fancy word for a wrong answer."
- Clarification: A heuristic provides an approximate or "good enough" solution. In many real-world situations, like package delivery routing or game AI, an approximate answer found quickly is far more valuable than a perfect answer that takes days to compute.
Summary
Algorithmic efficiency is a fundamental concept for evaluating the practicality of a computational solution. It is not enough for an algorithm to be correct; it must also be efficient enough to solve the problem in a reasonable timeframe with the available resources. We measure efficiency by analyzing the number of steps an algorithm takes relative to the size of its input. This allows us to classify algorithms as running in "reasonable" (polynomial) or "unreasonable" (exponential) time. For problems where optimal solutions are too slow to find, heuristics provide a powerful tool for finding practical, approximate solutions. Finally, the existence of undecidable problems shows that there are hard limits to what can be computed.