Algorithms
The underlying rules of programs
What is an Algorithm?
The algorithm can be defined as ” A set of finite rules or instructions to be followed in calculations or other problem-solving operations ”
- An algorithm is a set of commands that must be followed for a computer to perform calculations or other problem-solving operations.
- According to its formal definition, an algorithm is a finite set of instructions carried out in a specific order to perform a particular task.
- It is not the entire program or code; it is simple logic to a problem represented as an informal description in the form of a flowchart or pseudocode.
- Problem: A problem can be defined as a real-world problem or real-world instance problem for which you need to develop a program or set of instructions. An algorithm is a set of instructions.
- Algorithm: An algorithm is defined as a step-by-step process that will be designed for a problem.
- Input: After designing an algorithm, the algorithm is given the necessary and desired inputs.
- Processing unit: The input will be passed to the processing unit, producing the desired output.
- Output: The outcome or result of the program is referred to as the output.
Characteristics of an Algorithm
- Input: An algorithm requires some input values. An algorithm can be given a value other than 0 as input.
- Output: At the end of an algorithm, you will have one or more outcomes.
- Unambiguity: A perfect algorithm is defined as unambiguous, which means that its instructions should be clear and straightforward.
- Finiteness: An algorithm must be finite. Finiteness in this context means that the algorithm should have a limited number of instructions, i.e., the instructions should be countable.
- Effectiveness: Because each instruction in an algorithm affects the overall process, it should be adequate.
- Language independence: An algorithm must be language-independent, which means that its instructions can be implemented in any language and produce the same results.
Why do we need Algorithms?
- Scalability: It helps us to understand the scalability. When we have a big real-world problem, we need to scale it down into small-small steps to easily analyze the problem.
- Performance: The real world is not easily broken down into smaller steps. If the problem can be easily broken into smaller steps means that the problem is feasible.
How to Design an Algorithm?
In order to write an algorithm, the following things are needed as a pre-requisite:
- The problem that is to be solved by this algorithm i.e. clear problem definition.
- The constraints of the problem must be considered while solving the problem.
- The input to be taken to solve the problem.
- The output is to be expected when the problem is solved.
- The solution to this problem is within the given constraints.
Then the algorithm is written with the help of the above parameters such that it solves the problem.
Now we will look at an example of an algorithm in programming.
We will write an algorithm to add two numbers entered by the user.
The following are the steps required to add two numbers entered by the user:
Step 1: Start
Step 2: Declare variables num1, num2 and sum.
Step 3: Read values num1 and num2.
Step 4: Add num1 and num2 and assign the result to sum.
sum←num1+num2
Step 5: Display sum
Step 6: Stop
Factors of an Algorithm
The following are the factors to consider when designing an algorithm:
- Modularity: This feature was perfectly designed for the algorithm if you are given a problem and break it down into small-small modules or small-small steps, which is a basic definition of an algorithm.
- Correctness: An algorithm’s correctness is defined as when the given inputs produce the desired output, indicating that the algorithm was designed correctly. An algorithm’s analysis has been completed correctly.
- Maintainability: It means that the algorithm should be designed in a straightforward, structured way so that when you redefine the algorithm, no significant changes are made to the algorithm.
- Functionality: It takes into account various logical steps to solve a real-world problem.
- Robustness: Robustness refers to an algorithm’s ability to define your problem clearly.
- User-friendly: If the algorithm is difficult to understand, the designer will not explain it to the programmer.
- Simplicity: If an algorithm is simple, it is simple to understand.
- Extensibility: Your algorithm should be extensible if another algorithm designer or programmer wants to use it.
Importance of Algorithms
- Theoretical importance: When any real-world problem is given to us and we break the problem into small-small modules. To break down the problem, we should know all the theoretical aspects.
- Practical importance: As we know that theory cannot be completed without practical implementation. So, the importance of algorithms can be considered as both theoretical and practical.
Approaches of Algorithm
The following are the approaches used after considering both the theoretical and practical importance of designing an algorithm:
- Brute force algorithm: The general logic structure is applied to design an algorithm. It is also known as an exhaustive search algorithm that searches all the possibilities to provide the required solution. Such algorithms are of two types:
- Optimizing: Finding all the solutions to a problem and then taking out the best solution or if the value of the best solution is known then it will terminate if the best solution is known.
- Sacrificing: As soon as the best solution is found, then it will stop.
- Divide and conquer: It is a very implementation of an algorithm. It allows you to design an algorithm in a step-by-step variation. It breaks down the algorithm to solve the problem in different methods. It allows you to break down the problem into different methods, and valid output is produced for the valid input. This valid output is passed to some other function.
- Greedy algorithm: It is an algorithm paradigm that makes an optimal choice on each iteration with the hope of getting the best solution. It is easy to implement and has a faster execution time. But, there are very rare cases in which it provides the optimal solution.
- Dynamic programming: It makes the algorithm more efficient by storing the intermediate results. It follows five different steps to find the optimal solution for the problem:
- It breaks down the problem into a subproblem to find the optimal solution.
- After breaking down the problem, it finds the optimal solution out of these subproblems.
- Stores the result of the subproblems is known as memorization.
- Reuse the result so that it cannot be recomputed for the same subproblems.
- Finally, it computes the result of the complex program.
- Branch and Bound Algorithm: The branch and bound algorithm can be applied to only integer programming problems. This approach divides all the sets of feasible solutions into smaller subsets. These subsets are further evaluated to find the best solution.
- Randomized Algorithm: As we have seen in a regular algorithm, we have predefined input and required output. Those algorithms that have some defined set of inputs and required output, and follow some described steps are known as deterministic algorithms. What happens when the random variable is introduced in the randomized algorithm? In a randomized algorithm, some random bits are introduced by the algorithm and added to the input to produce the output, which is random in nature. Randomized algorithms are simpler and more efficient than the deterministic algorithm.
- Backtracking: Backtracking is an algorithmic technique that solves the problem recursively and removes the solution if it does not satisfy the constraints of a problem.
The major categories of algorithms are given below:
- Sort: Algorithm developed for sorting the items in a certain order.
- Search: Algorithm developed for searching the items inside a data structure.
- Delete: Algorithm developed for deleting the existing element from the data structure.
- Insert: Algorithm developed for inserting an item inside a data structure.
- Update: Algorithm developed for updating the existing element inside a data structure.
How to analyze an Algorithm?
For a standard algorithm to be good, it must be efficient. Hence the efficiency of an algorithm must be checked and maintained. It can be in two stages:
- Priori Analysis: “Priori” means “before”. Hence Priori analysis means checking the algorithm before its implementation. In this, the algorithm is checked when it is written in the form of theoretical steps. This Efficiency of an algorithm is measured by assuming that all other factors, for example, processor speed, are constant and have no effect on the implementation. This is done usually by the algorithm designer. This analysis is independent of the type of hardware and language of the compiler. It gives the approximate answers for the complexity of the program.
- Posterior Analysis: “Posterior” means “after”. Hence Posterior analysis means checking the algorithm after its implementation. In this, the algorithm is checked by implementing it in any programming language and executing it. This analysis helps to get the actual and real analysis report about correctness(for every possible input/s if it shows/returns correct output or not), space required, time consumed etc. That is, it is dependent on the language of the compiler and the type of hardware used.
What is Algorithm complexity and how to find it?
An algorithm is defined as complex based on the amount of Space and Time it consumes. Hence the Complexity of an algorithm refers to the measure of the time that it will need to execute and get the expected output and the Space it will need to store all the data (input, temporary data and output). Hence these two factors define the efficiency of an algorithm.
The two factors of Algorithm Complexity are:
- Time Factor: Time is measured by counting the number of key operations such as comparisons in the sorting algorithm.
- Space Factor: Space is measured by counting the maximum memory space required by the algorithm to run/execute.
Therefore the complexity of an algorithm can be divided into two types:
Time Complexity
The amount of time required to complete an algorithm’s execution is called time complexity. The big O notation is used to represent an algorithm’s time complexity. The asymptotic notation for describing time complexity, in this case, is big O notation. The time complexity is calculated primarily by counting the number of steps required to complete the execution. Let’s understand the time complexity through an example.
sum=0;
// Suppose we have to calculate the sum of n numbers.
for i=1 to n
sum=sum+i;
// when the loop ends then sum holds the sum of the n numbers
return sum;
In the above code, the time complexity of the loop statement will be at least n, and if the value of n increases, then the time complexity also increases. While the complexity of the code, i.e., return sum will be constant as its value is not dependent on the value of n and will provide the result in one step only. We generally consider the worst-time complexity as it is the maximum time taken for any given input size.
Space Complexity
The amount of space an algorithm requires to solve a problem and produce an output is called its space complexity. Space complexity, like time complexity, is expressed in big O notation.
The space is required for an algorithm for the following reasons:
- To store program instructions.
- To store track of constant values.
- To store track of variable values.
- To store track of function calls, jumping statements, and so on.
Space Complexity = Auxiliary Space + Input Size
How to express an Algorithm?
- Natural Language:- Here we express the Algorithm in the natural English language. It is too hard to understand the algorithm from it.
- Flow Chat:- Here we express the Algorithm by making a graphical/pictorial representation of it. It is easier to understand than Natural Language.
- Pseudo Code:- Here we express the Algorithm in the form of annotations and informative text written in plain English which is very much similar to the real code but as it has no syntax like any of the programming languages, it can’t be compiled or interpreted by the computer. It is the best way to express an algorithm because it can be understood by even a layman with some school-level programming knowledge.
Types of Algorithms
The following are the types of algorithms:
- Search Algorithm
- Sort Algorithm
Every day, you look for something in your daily life. Similarly, in the case of a computer, a large amount of data is stored in the computer, and whenever a user requests data, the computer searches for that data in the memory and returns it to the user. There are primarily two methods for searching data in an array:
The search algorithm is of two types:
Linear Search
Linear search is a simple algorithm that begins searching for an element or a value at the beginning of an array and continues until the required element is not found. It compares the element to be searched with all the elements in an array; if a match is found, the element index is returned; otherwise, -1 is returned. This algorithm can be applied to an unsorted list.
Binary Search
A binary algorithm is the most basic algorithm, and it searches for elements very quickly. It is used to find an element in a sorted list. To implement the binary algorithm, the elements must be stored in sequential order or sorted. If the elements are stored randomly, binary search cannot be implemented.
Sort Algorithm
Sorting algorithms rearrange elements in an array or a given data structure in ascending or descending order. The comparison operator decides the new order of the elements.
Why do we need a sorting algorithm?
- An efficient sorting algorithm is required for optimizing the efficiency of other algorithms like binary search algorithm as a binary search algorithm requires an array to be sorted in a particular order, mainly in ascending order.
- It produces information in a sorted order, which is a human-readable format.
- Searching for a particular element in a sorted list is faster than the unsorted list.
Advantages of Algorithms
- It is easy to understand.
- An algorithm is a step-wise representation of a solution to a given problem.
- In an Algorithm the problem is broken down into smaller pieces or steps hence, it is easier for the programmer to convert it into an actual program.
Disadvantages of Algorithms
- Writing an algorithm takes a long time so it is time-consuming.
- Understanding complex logic through algorithms can be very difficult.
- Branching and Looping statements are difficult to show in Algorithms.
Conclusion
In conclusion, algorithms have transformed our world, providing us with new opportunities and efficiencies. However, we must remain vigilant and proactive in ensuring that algorithms are developed, implemented, and regulated in a manner that aligns with our ethical values and societal well-being. By doing so, we can harness the power of algorithms to create a more inclusive, fair, and equitable future for all.