Download as pdf or txt
Download as pdf or txt
You are on page 1of 9

22/08/2020 MFDS-Assignment2-2019hc04888.

py

1 # -*- coding: utf-8 -*-


2 """MFDS-Assignment-2 - 2019hc04888 - Gowtham S Question 1.ipynb
3
4 Automatically generated by Colaboratory.
5
6 Original file is located at
7   https://colab.research.google.com/drive/1OmCp62MG2cd9kUjeoVjpN9ZkCKiUAIgN
8 """
9
10 import logging
11 import time
12
13 import matplotlib.pyplot as plt
14 import numpy as np
15
16 # Define Logger for Logging.
17 logger = logging.getLogger("MFDS-Assignment2-2019hc04888")
18 logger.setLevel(logging.DEBUG)
19 conHandler = logging.StreamHandler()
20 conHandler.setLevel(logging.DEBUG)
21 formatter = logging.Formatter('%(asctime)s %(name)s:%(funcName)-25.25s %
(levelname)-7s: %(message)s')
22 conHandler.setFormatter(formatter)
23 logger.addHandler(conHandler)
24
25 # Constants
26 NAIVE = "naive"
27 WARSHALL = "warshall"
28 IMAGE_NAME = "assignment_2_.png"
29
30 matrix_order = []
31 naive_time = []
32 warshall_time = []
33
34 class PlotTransitiveClosureLogPlot:
35    def __init__(self):
36        plt.loglog(matrix_order, naive_time, label="naive")
37        plt.loglog(matrix_order, warshall_time, label="warshall")
38        plt.legend()
39        plt.xscale("linear")
40        plt.title('Naive vs Warshall Log-Log Plot')
41        plt.xlabel('Order of Matrix')
42        plt.ylabel('Log-Log(RunTime)')
43        plt.savefig(IMAGE_NAME, dpi=100)
44        plt.show()
45        logger.info(f"Log Log Plot Image saved in {IMAGE_NAME}")
46
47 class FindOrderOfAlgorithms:
48
49    def __init__(self):
50        naive_order = np.polyfit(np.array(np.log(matrix_order)),
np.array(np.log(naive_time)), 1)[0]
51        warshall_order = np.polyfit(np.array(np.log(matrix_order)),
np.array(np.log(warshall_time)), 1)[0]
52        logger.info(f'Order of Naive: {naive_order}')
53        logger.info(f'Order of WarShall: {warshall_order}')
54
55 def log_algorithm_time(func):
56    """
57   Decorator to calculate Runtime..
localhost:4649/?mode=python 1/3
22/08/2020 MFDS-Assignment2-2019hc04888.py

58   It accept Callable as args and return Callable after wrapping it with


time calculation.
59   It is always preferred to not have duplicate code, Based on same
programming rule, we have written this decorator.
60   Args:
61       func:
62   Returns:
63   """
64    def wrapper(*args, **kwargs):
65        start_time = time.time()
66        func(*args, **kwargs)
67        total_time = time.time() - start_time
68        if func.__name__ == "naive_algorithm":
69            naive_time.append(total_time)
70        else:
71            warshall_time.append(total_time)
72        logger.debug(f'{func.__name__} completed in {total_time}')
73    return wrapper
74
75 @log_algorithm_time
76 def warshall_algorithm(matrix, order):
77    """
78   Warshall Algorithm
79   Args:
80       matrix:
81       order:
82   Returns:
83   """
84    logger.debug(f"Finding Transitive Closure using warhsall_algorithm for
order {order}")
85    assert (len(row) == len(matrix) for row in matrix)
86    for k in range(order):
87        for i in range(order):
88            for j in range(order):
89                matrix[i][j] = matrix[i][j] or (matrix[i][k] and matrix[k]
[j])
90
91 @log_algorithm_time
92 def naive_algorithm(matrix, order, results):
93    """
94   Naive Algorithm
95   Args:
96       matrix:
97       order:
98       results:
99   Returns:
100   """
101    logger.debug(f"Finding Transitive Closure using naive_algorithm for order
{order}")
102    matrix_a = matrix
103    matrix_b = matrix_a
104
105    for i in range(order):
106        for x in range(order):
107            for j in range(order):
108                for k in range(order):
109                    results[k][i] = matrix_a[k][i] or matrix_b[k][i] or
results[k][i] or (matrix_a[k][j] and
110                                                                            
             matrix_b[j][i])

localhost:4649/?mode=python 2/3
22/08/2020 MFDS-Assignment2-2019hc04888.py

111
112 def compare_algorithm(matrix, order):
113    """
114   Function to call both algorithm for each order
115   Args:
116       matrix:
117       order:
118   Returns:
119   """
120    results = np.zeros((order, order))  # Zero Matrix to store result.
121    warshall_algorithm(matrix=matrix, order=order)
122    naive_algorithm(matrix=matrix, order=order, results=results)
123
124 def main(order):
125    """
126   Entry Point.
127   Args:
128       order:
129   Returns:
130   """
131
132    # Test/Sample Matrix to verify the Implementation.
133    # First Matrix is taken from Lecture PPT and other from Book to verify
the answers
134    # order = 4
135    # matrix = [[1, 0, 0, 1],
136    #           [0, 1, 1, 0],
137    #           [0, 0, 0, 1],
138    #           [0, 0, 0, 0]]
139    # matrix = [[1, 1, 0, 1],
140    #           [0, 1, 1, 0],
141    #           [0, 0, 1, 1],
142    #           [0, 0, 0, 1]
143    #           ]
144
145    matrix_order.append(order)
146    n_dimension_values = np.random.choice([0, 1], size=(order, order))
147    matrix = np.array(n_dimension_values).reshape(order, order)
148    compare_algorithm(matrix=matrix, order=order)
149
150 if __name__ == '__main__':
151    # Numbers between 10 to 100
152    for order_val in range(10, 101):
153        main(order=order_val)
154    PlotTransitiveClosureLogPlot()
155    FindOrderOfAlgorithms()
156
157

localhost:4649/?mode=python 3/3
Log Log Plot

Time Complexity

You might also like