"Without loss of generality, may all your theorems be proved." - Rashid.
"I f thy theorems fail deduction reasoning thou shalt apply induction reasoning with the most meticulous care." - Rashid.
An algorithm, named after the ninth century scholar Abu Jafar Muhammad Ibn Musu Al-Khowarizmi, is defined as follows: Roughly speaking: An algorithm is a set of rules for carrying out calculation either by hand or on a machine. An algorithm is a finite step-by-step procedure to achieve a required result. An algorithm is a sequence of computational steps that transform the input into the output. An algorithm is a sequence of operations performed on data that have to be organized in data structures. An algorithm is an abstraction of a program to be executed on a physical machine (model of Computation). The most famous algorithm in history dates well before the time of the ancient Greeks: this is the Euclid's algorithm for calculating the greatest common divisor of two integers. This theorem appeared as the solution to the Proposition II in the Book VII of Euclid's "Elements." Euclid's "Elements" consists of thirteen books, which contain a total number of 465 propositions.
The Classic Multiplication Algorithm 1. Multiplication, the American way: Multiply the multiplicand one after another by each digit of the multiplier taken from right to left.
2. Multiplication, the English way: Multiply the multiplicand one after another by each digit of the multiplier taken from left to right.
Algorithmic is a branch of computer science that consists of designing and analyzing computer algorithms 1. The design pertain to i. The description of algorithm at an abstract level by means of a pseudo language, and ii. Proof of correctness that is, the algorithm solves the given problem in all cases. 2. The analysis deals with performance evaluation (complexity analysis).
We start with defining the model of computation, which is usually the Random Access Machine (RAM) model, but other models of computations can be use such as PRAM. Once the model of computation has been defined, an algorithm can be describe using a simple language (or pseudo language) whose syntax is close to programming language such as C or java.
Algorithm's Performance Two important ways to characterize the effectiveness of an algorithm are its space complexity and time complexity. Time complexity of an algorithm concerns determining an expression of the number of steps needed as a function of the problem size. Since the step count measure is somewhat coarse, one does not aim at obtaining an exact step count. Instead, one attempts only to get asymptotic bounds on the step count. Asymptotic analysis makes use of the O (Big Oh) notation. Two other notational constructs used by computer scientists in the analysis of algorithms are (Big Theta) notation and (Big Omega) notation. The performance evaluation of an algorithm is obtained by totaling the number of occurrences of each operation when running the algorithm. The performance of an algorithm is evaluated as a function of the input size n and is to be considered modulo a multiplicative constant.
The following notations are commonly use notations in performance analysis and used to characterize the complexity of an algorithm. -Notation (Same order) This notation bounds a function to within constant factors. We say f(n) = (g(n)) if there exist positive constants n 0 , c 1 and c 2 such that to the right of n 0 the value of f(n) always lies between c 1 g(n) and c 2 g(n) inclusive.
In the set notation, we write as follows: (g(n)) = {f(n) : there exist positive constants c 1 , c 1 , and n 0 such that 0 c 1 g(n) f(n) c 2 g(n) for all n n 0 } We say that is g(n) an asymptotically tight bound for f(n).
Graphically, for all values of n to the right of n 0 , the value of f(n) lies at or above c 1 g(n) and at or below c 2 g(n). In other words, for all n n 0 , the function f(n) is equal tog(n) to within a constant factor. We say that g(n) is an asymptotically tight bound for f(n). In the set terminology, f(n) is said to be a member of the set (g(n)) of functions. In other words, because O(g(n)) is a set, we could write f(n) (g(n)) to indicate that f(n) is a member of (g(n)). Instead, we write f(n) = (g(n)) to express the same notation. Historically, this notation is "f(n) = (g(n))" although the idea that f(n) is equal to something called (g(n)) is misleading. Example: n 2 /2 2n = (n 2 ), with c 1 = 1/4, c 2 = 1/2, and n 0 = 8.
-Notation (Upper Bound) This notation gives an upper bound for a function to within a constant factor. We write f(n) = O(g(n)) if there are positive constants n 0 and c such that to the right of n 0 , the value of f(n) always lies on or below c g(n). In the set notation, we write as follows: For a given function g(n), the set of functions (g(n)) = {f(n): there exist positive constants c and n 0 such that 0 f(n) c g(n) for all n n 0 } We say that the function g(n) is an asymptotic upper bound for the function f(n). We use -notation to give an upper bound on a function, to within a constant factor.
Graphically, for all values of n to the right of n 0 , the value of the function f(n) is on or below g(n). We write f(n) = O(g(n)) to indicate that a function f(n) is a member of the set (g(n)) i.e. f(n) (g(n)) Note that f(n) = (g(n)) implies f(n) = (g(n)), since -notation is a stronger notation than -notation. Example: 2n 2 = (n 3 ), with c = 1 and n 0 = 2.
Equivalently, we may also define f is of order g as follows: If f(n) and g(n) are functions defined on the positive integers, then f(n) is (g(n)) if and only if there is a c > 0 and an n 0 > 0 such that | f(n) | | g(n) | for all n n 0
Historical Note: The notation was introduced in 1892 by the German mathematician Paul Bachman.
-Notation (Lower Bound) This notation gives a lower bound for a function to within a constant factor. We write f(n) = (g(n)) if there are positive constants n 0 and c such that to the right of n 0 , the value of f(n) always lies on or above c g(n). In the set notation, we write as follows: For a given function g(n), the set of functions (g(n)) = {f(n) : there exist positive constants c and n 0 such that 0 c g(n) f(n) for all n n 0 } We say that the function g(n) is an asymptotic lower bound for the function f(n).
The intuition behind -notation is shown above. Example: n = (lg n), with c = 1 and n 0 = 16.
Algorithm Analysis The complexity of an algorithm is a function g(n) that gives the upper bound of the number of operation (or running time) performed by an algorithm when the input size isn. There are two interpretations of upper bound. Worst-case Complexity The running time for any given size input will be lower than the upper bound except possibly for some values of the input where the maximum is reached. Average-case Complexity The running time for any given size input will be the average number of operations over all problem instances for a given size. Because, it is quite difficult to estimate the statistical behavior of the input, most of the time we content ourselves to a worst case behavior. Most of the time, the complexity of g(n) is approximated by its family o(f(n)) where f(n) is one of the following functions. n (linear complexity), log n (logarithmic complexity), n a where a 2 (polynomial complexity), a n (exponential complexity).
Optimality Once the complexity of an algorithm has been estimated, the question arises whether this algorithm is optimal. An algorithm for a given problem is optimal if its complexity reaches the lower bound over all the algorithms solving this problem. For example, any algorithm solving the intersection of n segments problem will execute at least n 2 operations in the worst case even if it does nothing but print the output. This is abbreviated by saying that the problem has (n 2 ) complexity. If one finds an O(n 2 ) algorithm that solve this problem, it will be optimal and of complexity (n 2 ).
Reduction Another technique for estimating the complexity of a problem is the transformation of problems, also called problem reduction. As an example, suppose we know a lower bound for a problem A, and that we would like to estimate a lower bound for a problem B. If we can transform A into B by a transformation step whose cost is less than that for solving A, then B has the same bound as A. The Convex hull problem nicely illustrates "reduction" technique. A lower bound of Convex-hull problem established by reducing the sorting problem (complexity: (n logn)) to the Convex hull problem.
Binary Search Tree
Binary Search tree is a binary tree in which each internal node x stores an element such that the element stored in the left subtree of x are less than or equal to x and elements stored in the right subtree of x are greater than or equal to x. This is called binary-search-tree property. The basic operations on a binary search tree take time proportional to the height of the tree. For a complete binary tree with node n, such operations runs in (lg n) worst-case time. If the tree is a linear chain of n nodes, however, the same operations takes (n) worst-case time.
The height of the Binary Search Tree equals the number of links from the root node to the deepest node.
Implementation of Binary Search Tree Binary Search Tree can be implemented as a linked data structure in which each node is an object with three pointer fields. The three pointer fields left, right and p point to the nodes corresponding to the left child, right child and the parent respectively NIL in any pointer field signifies that there exists no corresponding child or parent. The root node is the only node in the BTS structure with NIL in its p field.
Inorder Tree Walk During this type of walk, we visit the root of a subtree between the left subtree visit and right subtree visit. INORDER-TREE-WALK (x) If x NIL then INORDER-TREE-WALK (left[x]) print key[x] INORDER-TREE-WALK (right[x]) It takes (n) time to walk a tree of n nodes. Note that the Binary Search Tree property allows us to print out all the elements in the Binary Search Tree in sorted order.
Preorder Tree Walk In which we visit the root node before the nodes in either subtree. PREORDER-TREE-WALK (x) If x not equal NIL then PRINT key[x] PREORDER-TREE-WALK (left[x]) PREORDER-TREE-WALK (right[x])
Postorder Tree Walk In which we visit the root node after the nodes in its subtrees. POSTORDER-TREE-WALk (x) If x not equal NIL then POSTORDER-TREE-WALK (left[x]) PREORDER-TREE-WALK (right[x]) PRINT key [x] It takes O(n) time to walk (inorder, preorder and pastorder) a tree of n nodes.
Algorithms and Flowcharts An algorithm is a description of how to carry out a process. An algorithm lists the steps that must be followed to complete the process. Algorithms can be described in English but such descriptions are often ambiguous and open to misunderstanding. Therefore various formal methods of describing algorithms have been developed. The simplest of these is the flowchart. A flowchart consists of a sequence of instructions linked together by arrows to show the order in which the instructions must be carried out. Each instruction is put into a box. The boxes are different shapes depending upon what the instruction is. The main four types of box are :
Flowcharts are often used to describe in detail algorthms that will be carried out by a computer. When a computer carries out an algorithm the computer is said to execute the algorithm. Execution is also sometimes referred to as running. Here are some example situtations in which flowcharts are often used : Control Systems : The operation of a control system can be described using a flowhcart. Macros : The actions that a macro should execute can be planned using a flowchart. Computer Programs : Computer programs can be designed by drawing flowcharts to show what insturctions the program should execute. Sometimes a more general view of how an information system will operate is required. A flowchart for a complete information system would cover many pages of paper and would be very difficult to produce and understand. A more general description of how an information system operates can be given by using a system flowchart. Example Flowcharts Flowchart Example One : Simple Greenhouse Temperature Control System A greenhouse temperature control system consists of : A temperature sensor. A heater. The system is used to keep the temperature of the greenhouse above 20C. If the temperature drops below 20C then a heater is turned on to warm the greenhouse up. The system uses two devices : Input Sensors Output Devices Temperature Sensor Heater The operation of the system is described by this flowchart
Flowchart Example Two : Macro To Sort A Football League Table A spreadsheet has been created which shows the league positions of some football teams in a league. Whenever a team plays a match the team's points score and position in the league may change. After each match the league table must be sorted to put the teams in the correct order. The actions required to complete this task in the spreadsheet are : Select the area of the spreadsheet that contains the data to be sorted (the league table). Choose which piece of information (e.g. points) in the table you want to use to order the data. Select whether you want to put the data in ascending or descending order. A macro has been created to automate this process. The macro is described by this flowchart :
System Flowcharts Flowcharts describe in detail how a process will be carried out. Sometimes during the development of an information system it is useful to be able to produce a more general description of how a system will work. A system flowchart shows in general terms the operations that will be performed on information in an information system. The arrows on a system flowchart show the direction that data will flow in around the system rather than the order in which the operations will be carried out. Many more symbols are used on a system flowchart than on a normal flowchart. These are the symbols that may be used :
System Flowchart Example : Car Repair Garage A car repair garage uses a computer system to produce invoices and keep track of the parts it has in stock. The system uses two files : Stock File : Contains details of all parts that are in stock. Orders File : Contains details of all parts that are on order. When a repair is completed the mechanic records the parts that were used on a form. These parts are then entered into the computer by an operator. The list of parts that is entered is checked against the stock list to reduce the likelihood of the operator making a mistake. If the operator enters the name of a part that does not exist then an error report is displayed. When the parts list has been entered the cost of the parts is looked up in the stock file and an invoice (bill) is printed for the customer. Every night the computer system checks the stock file. A report is printed to indicate which parts need to be ordered from the garage's suppliers. Details of any orders are placed in the orders file. When a delivery of new parts is made to the garage the person making the delivery gives the garage a delivery note. The delivery note contains a list of the parts that have been delivered. The list of new parts is entered into the computer by an operator. If any parts have been delivered that were not ordered then an error report is printed. When an order is delivered the information about the order is removed from the orders file and the stock file is updated. The structure of this system can be shown using the following system flowchart :
Questions (1) Explain these important terms : a) Algorithm b) Flowchart c) System Flowchart (2) What is the difference between a flowchart and a system flowchart ? (3) Why are flowcharts usually used to describe algorithms instead of written descriptions ? (4) Flowcharts can also be used to describe activities that humans carry out. Draw a flowchart for one of these activities : a) Making a telephone call. b) Making a cup of tea. c) Repairing a bicycle tyre. Include as much detail as possible. (5) Choose an information system such as a spreadsheet or database that you have created. Draw either a system flowchart or a flowchart to explain how the system operates. (C) P. Meakin 1998