Analysis of Algorithms#
The analysis of algorithms and data structures are two fundamental areas of computer science that are closely related. An algorithm is a step-by-step procedure for solving a computational problem, while a data structure is a way of organizing and storing data in a computer program. The choice of algorithm and data structure can significantly impact the performance of a program.
The analysis of algorithms involves the study of the efficiency and performance of algorithms, typically measured in terms of time complexity and space complexity. Time complexity refers to the amount of time it takes for an algorithm to solve a problem as the input size grows larger. Space complexity refers to the amount of memory an algorithm requires to solve a problem.
Data structures are used to store and organize data in a way that allows efficient access and manipulation. The choice of data structure can have a significant impact on the performance of an algorithm. For example, if a program needs to frequently search and retrieve items from a collection, a hash table or a binary search tree might be a more efficient data structure than a linked list.
Together, the analysis of algorithms and data structures are essential for designing and implementing efficient computer programs. By choosing the best algorithms and data structures for a given problem, programmers can significantly improve the performance and scalability of their software.
Problem?
a task to be performed
best thought in terms of (well-defined) inputs and outputs
problem definition does not impose constraints on how the problem is solved but often includes resource constraints
Algorithm?
a sequence of steps followed to solve a problem
it must be correct and composed of a finite number of concrete steps
there can be no ambiguity
it must terminate
Program?
a representation of an algorithm in some programming language
Analysis of algorithms#
Algorithms
“Any well-defined computational procedure that takes some value, or set of values, as input and produces some value, or set of values, as output.”
—[Cormen et al., Introduction to Algorithms, 3rd.Ed.]
Time Complexity (running time)
Space Complexity (memory)
Resources typically depend on input size
Developing a usable algorithm#
The building blocks of algorithms
An algorithm is a step by step process that describes how to solve a problem in a way that always gives a correct answer. When there are multiple algorithms for a particular problem (and there often are!), the best algorithm is typically the one that solves it the fastest.
As computer programmers, we are constantly using algorithms, whether it’s an existing algorithm for a common problem, like sorting an array, or if it’s a completely new algorithm unique to our program. By understanding algorithms, we can make better decisions about which existing algorithms to use and learn how to make new algorithms that are correct and efficient. An algorithm is made up of three basic building blocks: sequencing, selection, and iteration.
Sequencing: An algorithm is a step-by-step process, and the order of those steps are crucial to ensuring the correctness of an algorithm.
Selection: Algorithms can use selection to determine a different set of steps to execute based on a Boolean expression.
Iteration: Algorithms often use repetition to execute steps a certain number of times or until a certain condition is met.
Example from CS50
Why analyze algorithms?#
Classify algorithms/problems
Predict performance/resources
Provide guarantees
Understand underlying principles of problems
and…
Analyzing computational cost#
Run algorithm
Measure actual time
Analyze algorithm
Develop Model
Empirical analysis (timing)#
Implement algorithm
Run on different input sizes
Record actual running times
Calculate hypothesis
Predict and validate
Timing Algorithms#
Example 1
… mathematical constant that is the base of the natural logarithm. It is approximately equal to 2.71828.
Applications?
Euler used the letter \(e\) for exponents, but the letter is now widely associated with his name. It is commonly used in a wide range of applications, including population growth of living organisms and the radioactive decay of heavy elements like uranium by nuclear scientists. It can also be used in trigonometry, probability, and other areas of applied mathematics.
visualizations
Algorithms#
1long double euler1 (int n) {
2 long double sum = 0;
3 long double fact;
4 for (int i = 0; i <= n; i++) {
5 fact = 1;
6 for (int j = 2; j <= i; j++) {
7 fact *= j;
8 }
9 sum += (1.0/fact);
10 }
11 return sum;
12}
1long double euler2 (int n) {
2 long double sum = 0;
3 long double fact = 1;
4 for (int i = 0; i <= n; i++) {
5 sum += (1.0/fact);
6 fact *= (i + 1);
7 }
8 return sum;
9}
Example 2
1uint64_t fibI(uint16_t n){
2 uint64_t sum;
3 uint64_t prev[] = {0,1};
4 if (n < 2) return n;
5 for (uint16_t i = 2; i <= n; i++) {
6 sum = prev[0] + prev[1];
7 prev[0] = prev[1];
8 prev[1] = sum;
9 }
10 return sum;
11}
1uint64_t fibR (uint16_t n) {
2 if (n < 2) return n;
3 else return fibR(n-1) + fibR(n-2);
4}
1void time_func(uint16_t n, const char *name) {
2 uint64_t val;
3 Clock::time_point tic,toc;
4 if (! strcmp(name,"Iter")) {
5 tic = Clock::now();
6 val = fib_iter(n);
7 toc = Clock::now();
8 }
9 if (! strcmp(name,"Rec")) {
10 tic = Clock::now();
11 val = fib_rec(n);
12 toc = Clock::now();
13 }
14 std::cout << name << "fib(" << n << "):\t"
15 << std::fixed << std::setprecision(4)
16 << Seconds(toc-tic).count() << "sec.\tOutput:"
17 << val << std::endl;
18}
19
20int main (int argc, char** argv) {
21 if (argc != 3) {
22 std::cout << "Usage:./fib<n><alg>\n";
23 std::cout << "\t<n>\tn-th term to be calculated\n";
24 std::cout << "\t<alg>\t algorithm to be used(RecorIter)\n";
25 return 0;
26 }
27 uint16_t n = (uint16_t)
28 atoi(argv[1]);
29 time_func(n,argv[2]);
30}
Outcomes
Is this as expected?
Hypothesis
Complete the graph, what would it look like?
Limitations of empirical analysis#
Requires implementing several algorithms for the same problem
may be difficult and time consuming
implementation details also play a role (one particular algorithm may be “better written”)
Requires extensive testing
time consuming
choice of test cases might favor one of the algorithms
Variations in hardware, software, and operating system affect analysis