# How to Analyse an Algorithm?

Algorithm analysis is the process of evaluating the efficiency and effectiveness of algorithms by comparing them with respect to time, space etc. It involves studying the performance characteristics of algorithms to understand how they behave in terms of time complexity, space complexity, and other relevant factor.

What will you learn?

Algorithm analysis is crucial for making informed decisions about algorithm selection in software development and computer science. It helps developers and researchers understand the trade-offs between different algorithms and choose the most appropriate one for a given problem or application.

## Algorithm Analysis Approach

A priori analysis and a posteriori analysis are two approaches used in algorithm analysis to assess the efficiency or correctness of an algorithm. Let’s explore each of them:

### Priori Analysis:

A priori algorithm analysis involves predicting or estimating the performance characteristics of an algorithm before it is actually implemented or run. This approach is theoretical and relies on mathematical or analytical techniques to analyze the algorithm’s time and space complexity. It aims to provide insights into the algorithm’s behavior without the need for practical implementation or empirical testing.

Example: Big-O notation (Asymptotic Notation) is a common tool used in a priori analysis to express the upper bound of an algorithm’s time or space complexity in terms of the input size.

### Posteriori Analysis:

A posteriori analysis involves evaluating the performance of an algorithm based on empirical observations or measurements obtained from running the algorithm on actual data. This approach is practical and involves implementing the algorithm in a real-world setting. The algorithm is executed with various inputs, and its actual performance is measured in terms of time taken, memory usage, and other relevant metrics.

Example: Profiling tools and performance measurement techniques are used in a posteriori analysis to gather data about an algorithm’s runtime behavior and resource utilization.

### Priori & Posteriori Comparison:

• A priori analysis is more focused on theoretical predictions and mathematical reasoning so its independent of hardware.
• A posteriori analysis is concerned with practical implementation and real-world performance measurements on machine so its hardware dependent.

## Asymptotic Notations

Asymptotic notations are mathematical tools used in algorithm analysis to describe the efficiency of algorithms in terms of their running time or space requirements as the input size approaches infinity. These notations provide a concise way to express the growth rate of algorithms and make it easier to compare their performance. The three most commonly used asymptotic notations are Big-O, Big-Theta, and Big-Omega.

### Big-O Notation (O):

Big-O notation represents the upper bound of an algorithm’s growth rate. It describes the worst-case scenario of an algorithm’s time or space complexity.

$$f(n)= O(g(n))$$ if there exist constants c and k​ such that $$0 ≤ f(n) ≤ c⋅g(n)$$ for all $$n ≥ k$$.

Example

$$f(n)=2n^2+n$$ , then $$f(n)=O(n^2)$$ because $$2n^2+n ≤ c⋅n^2$$ for some constants c > 0 and k ≥ 0 and n ≥ k.

### Big-Omega Notation (Ω):

Big-Omega notation represents the lower bound of an algorithm’s growth rate. It describes the best-case scenario of an algorithm’s time or space complexity.

$$f(n)= \Omega(g(n))$$ if there exist constants c and k​ such that $$0 ≤ c⋅g(n) ≤ f(n)$$ for all $$n ≥ k$$.

Example: If f(n)=2n2+3n+1f(n)=2n2+3n+1, and g(n)=n2g(n)=n2, then f(n)=Ω(n2)f(n)=Ω(n2).

### Big-Theta Notation (Θ):

Big-Theta notation provides both upper and lower bounds, capturing the tightest possible growth rate of an algorithm. It describes the average-case scenario of an algorithm’s time or space complexity.

$$f(n)= \theta(g(n))$$ if there exist constants c and k​ such that $$0 ≤ c1⋅g(n) ≤ f(n) ≤ c2⋅g(n)$$ for all $$n ≥ k$$.

Example: If f(n)=2n2+3n+1f(n)=2n2+3n+1, and g(n)=n2g(n)=n2, then f(n)=Θ(n2)f(n)=Θ(n2).

These asymptotic notations are widely used in algorithm analysis for the following reasons:

• They provide a high-level, abstract view of an algorithm’s efficiency.
• They allow for comparison of algorithms without getting bogged down in specific implementation details.
• They are useful for understanding how algorithms scale with large input sizes.
• They help in making informed decisions about algorithm selection based on their theoretical performance characteristics.

## Complexity Precedence

$$1 ≤ log(logn) ≤ logn ≤ n^{1/2} ≤ n ≤ nlogn ≤ n^2 ≤ n^3 ≤ n^k ≤ 2^n ≤ 2^{n^k}$$

When analyzing algorithms, it’s common to use Big-O notation to express the upper bound of the growth rate, as it focuses on the worst-case scenario, which is often of primary concern in algorithmic analysis.

Categories DAA