aboutsummaryrefslogtreecommitdiff
path: root/src/Lecture7/slides/.ipynb_checkpoints/X1-ComputationalComplexity-checkpoint.ipynb
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano.tronto@gmail.com>2021-05-25 17:10:49 +0200
committerSebastiano Tronto <sebastiano.tronto@gmail.com>2021-05-25 17:10:49 +0200
commitd6c61d988bfa4255baf9cdae42db59ebee38363f (patch)
tree118ff3c2424e735149c145524965a4a337e50beb /src/Lecture7/slides/.ipynb_checkpoints/X1-ComputationalComplexity-checkpoint.ipynb
parent46eef66b1e1571c77dc828d7e950b129b4c8bfd0 (diff)
downloadmathsoftware-d6c61d988bfa4255baf9cdae42db59ebee38363f.tar.gz
mathsoftware-d6c61d988bfa4255baf9cdae42db59ebee38363f.zip
Added files
Diffstat (limited to 'src/Lecture7/slides/.ipynb_checkpoints/X1-ComputationalComplexity-checkpoint.ipynb')
-rw-r--r--src/Lecture7/slides/.ipynb_checkpoints/X1-ComputationalComplexity-checkpoint.ipynb394
1 files changed, 394 insertions, 0 deletions
diff --git a/src/Lecture7/slides/.ipynb_checkpoints/X1-ComputationalComplexity-checkpoint.ipynb b/src/Lecture7/slides/.ipynb_checkpoints/X1-ComputationalComplexity-checkpoint.ipynb
new file mode 100644
index 0000000..ab7dd49
--- /dev/null
+++ b/src/Lecture7/slides/.ipynb_checkpoints/X1-ComputationalComplexity-checkpoint.ipynb
@@ -0,0 +1,394 @@
1{
2 "cells": [
3 {
4 "cell_type": "markdown",
5 "metadata": {},
6 "source": [
7 "# Nested loops\n",
8 "\n",
9 "The following two functions compute sum and product of matrices, respectively.\n",
10 "\n",
11 "By counting the nested loops it is easy to see that `add()` is $O(n^2)$ while `prod()` is $O(n^3)$."
12 ]
13 },
14 {
15 "cell_type": "code",
16 "execution_count": 37,
17 "metadata": {},
18 "outputs": [
19 {
20 "name": "stdout",
21 "output_type": "stream",
22 "text": [
23 "Time for add: 0.00012074300000008975\n",
24 "Time for prod: 0.00036587199999971176\n"
25 ]
26 }
27 ],
28 "source": [
29 "from random import randint\n",
30 "import time\n",
31 "\n",
32 "def add(A, B):\n",
33 " S = [[0] * len(A) for i in range(len(A))]\n",
34 " for i in range(len(A)):\n",
35 " for j in range(len(A)):\n",
36 " S[i][j] = A[i][j] + B[i][j]\n",
37 " return S\n",
38 "\n",
39 "def prod(A, B):\n",
40 " S = [[0] * len(A) for i in range(len(A))]\n",
41 " for i in range(len(A)):\n",
42 " for j in range(len(A)):\n",
43 " for k in range(len(A)):\n",
44 " S[i][j] = S[i][j] + A[i][k] * B[k][j]\n",
45 " return S\n",
46 "\n",
47 "N = 10\n",
48 "A = [ [randint(0,100) for i in range(N)] for j in range(N) ]\n",
49 "B = [ [randint(0,100) for i in range(N)] for j in range(N) ]\n",
50 "\n",
51 "t0 = time.process_time()\n",
52 "add(A,B)\n",
53 "t1 = time.process_time()\n",
54 "prod(A,B)\n",
55 "t2 = time.process_time()\n",
56 "\n",
57 "print(\"Time for add: \", t1-t0)\n",
58 "print(\"Time for prod:\", t2-t1)"
59 ]
60 },
61 {
62 "cell_type": "markdown",
63 "metadata": {},
64 "source": [
65 "# Sorting a list, slow version\n",
66 "\n",
67 "The following code implements a slow version of the so-called *insertion sort* alogithm\n",
68 "\n",
69 "Complexity: $O(n^2)$."
70 ]
71 },
72 {
73 "cell_type": "code",
74 "execution_count": 61,
75 "metadata": {},
76 "outputs": [
77 {
78 "name": "stdout",
79 "output_type": "stream",
80 "text": [
81 "Running time: 1.1012288430000012\n"
82 ]
83 }
84 ],
85 "source": [
86 "from random import randint\n",
87 "import time\n",
88 "\n",
89 "def correct_position(e, S):\n",
90 " for i in range(len(S)):\n",
91 " if S[i] > e:\n",
92 " return i\n",
93 " return len(S)\n",
94 "\n",
95 "def sort_list(L):\n",
96 " S = []\n",
97 " for e in L:\n",
98 " cp = correct_position(e, S)\n",
99 " S.insert(cp, e)\n",
100 " return S\n",
101 "\n",
102 "N = 10000\n",
103 "L = [randint(0,10**9) for i in range(N)]\n",
104 "\n",
105 "t0 = time.process_time()\n",
106 "sort_list(L)\n",
107 "t1 = time.process_time()\n",
108 "\n",
109 "print(\"Running time:\", t1-t0)"
110 ]
111 },
112 {
113 "cell_type": "markdown",
114 "metadata": {},
115 "source": [
116 "# Binary search\n",
117 "\n",
118 "The following code implements a binary search.\n",
119 "\n",
120 "Complexity: $O(\\log_2(n))$"
121 ]
122 },
123 {
124 "cell_type": "code",
125 "execution_count": 53,
126 "metadata": {},
127 "outputs": [
128 {
129 "name": "stdout",
130 "output_type": "stream",
131 "text": [
132 "The correct position of e = 658230309 in L is:\n",
133 "... 658211821 658224379 e 658234625 658246765 ...\n",
134 "\n",
135 "Time for sorting: 0.021211020999999164\n",
136 "Time for searching: 7.820199999741817e-05\n"
137 ]
138 }
139 ],
140 "source": [
141 "from random import randint\n",
142 "import time\n",
143 "\n",
144 "def binary_search(e, S, start, end):\n",
145 " if start == end:\n",
146 " return start\n",
147 " midpoint = (start+end) // 2\n",
148 " if e < S[midpoint]:\n",
149 " return binary_search(e, S, start, midpoint)\n",
150 " else:\n",
151 " return binary_search(e, S, midpoint+1, end)\n",
152 " \n",
153 "N = 100000\n",
154 "L = [randint(0,10**9) for i in range(N)]\n",
155 "e = randint(0,10**9)\n",
156 "\n",
157 "t0 = time.process_time()\n",
158 "L.sort() # Using Python's sort()\n",
159 "t1 = time.process_time()\n",
160 "i = binary_search(e, L, 0, len(L))\n",
161 "t2 = time.process_time()\n",
162 "print(\"The correct position of e =\", e, \"in L is:\")\n",
163 "print(\"...\", L[i-2], L[i-1], \"e\", L[i], L[i+1], \"...\")\n",
164 "print(\"\")\n",
165 "print(\"Time for sorting: \", t1-t0)\n",
166 "print(\"Time for searching:\", t2-t1)\n"
167 ]
168 },
169 {
170 "cell_type": "markdown",
171 "metadata": {},
172 "source": [
173 "# Sorting a list, fast version (with binary_search)\n",
174 "\n",
175 "The following code uses the function `binary_search()` above instead of `correct_position()` in our insertion sort algorithm.\n",
176 "\n",
177 "Complexity: $O(n\\log_2(n))$"
178 ]
179 },
180 {
181 "cell_type": "code",
182 "execution_count": 69,
183 "metadata": {},
184 "outputs": [
185 {
186 "name": "stdout",
187 "output_type": "stream",
188 "text": [
189 "Running time: 0.03710268399998995\n"
190 ]
191 }
192 ],
193 "source": [
194 "from random import randint\n",
195 "import time\n",
196 "\n",
197 "def binary_search(e, S, start, end):\n",
198 " if start == end:\n",
199 " return start\n",
200 " midpoint = (start+end) // 2\n",
201 " if e < S[midpoint]:\n",
202 " return binary_search(e, S, start, midpoint)\n",
203 " else:\n",
204 " return binary_search(e, S, midpoint+1, end)\n",
205 " \n",
206 "def sort_list(L):\n",
207 " S = []\n",
208 " for e in L:\n",
209 " cp = binary_search(e, S, 0, len(S)) # Changed here\n",
210 " S.insert(cp, e)\n",
211 " return S\n",
212 " \n",
213 "N = 10000\n",
214 "L = [randint(0,10**9) for i in range(N)]\n",
215 "\n",
216 "t0 = time.process_time()\n",
217 "sort_list(L)\n",
218 "t1 = time.process_time()\n",
219 "\n",
220 "print(\"Running time:\", t1-t0)"
221 ]
222 },
223 {
224 "cell_type": "markdown",
225 "metadata": {},
226 "source": [
227 "# Fast exponentiation\n",
228 "\n",
229 "The following cell contains two functions for computing $a^n$ ($n$ non-negative integer): a slow one that runs in $O(n)$ and a fast one that runs in $O(\\log_2(n))$. We compare these two also with Python's built-in operator `**`.\n",
230 "\n",
231 "Complexity: $O(n)$ for the slow algorithm, $O(\\log_2(n))$ for the other two."
232 ]
233 },
234 {
235 "cell_type": "code",
236 "execution_count": 30,
237 "metadata": {},
238 "outputs": [
239 {
240 "name": "stdout",
241 "output_type": "stream",
242 "text": [
243 "2.71828179834636\n",
244 "2.7182817863957984\n",
245 "2.7182817983473577\n",
246 "Time for slow_power(): 3.234879998000004\n",
247 "Time for fast_power(): 9.059099999575437e-05\n",
248 "Time for Python's **: 0.00010159500000384014\n"
249 ]
250 }
251 ],
252 "source": [
253 "import time\n",
254 "\n",
255 "def slow_power(a, n):\n",
256 " r = 1\n",
257 " for i in range(n):\n",
258 " r = r * a\n",
259 " return r\n",
260 "\n",
261 "def fast_power(a, n):\n",
262 " if n == 0:\n",
263 " return 1\n",
264 " if n%2 == 0:\n",
265 " return fast_power(a*a, n//2)\n",
266 " else:\n",
267 " return a * fast_power(a, n-1)\n",
268 "\n",
269 "a = 1.00000001\n",
270 "n = 100000000\n",
271 "\n",
272 "t0 = time.process_time()\n",
273 "print(slow_power(a, n))\n",
274 "t1 = time.process_time()\n",
275 "print(fast_power(a, n))\n",
276 "t2 = time.process_time()\n",
277 "print(a**n)\n",
278 "t3 = time.process_time()\n",
279 "\n",
280 "print(\"Time for slow_power():\", t1-t0)\n",
281 "print(\"Time for fast_power():\", t2-t1)\n",
282 "print(\"Time for Python's **: \", t3-t2)"
283 ]
284 },
285 {
286 "cell_type": "markdown",
287 "metadata": {},
288 "source": [
289 "# Fast gcd\n",
290 "\n",
291 "Complexity: $O(\\log_2(n))$"
292 ]
293 },
294 {
295 "cell_type": "code",
296 "execution_count": 31,
297 "metadata": {},
298 "outputs": [
299 {
300 "name": "stdout",
301 "output_type": "stream",
302 "text": [
303 "126\n",
304 "Running time: 0.00017707599999994272\n"
305 ]
306 }
307 ],
308 "source": [
309 "import time\n",
310 "\n",
311 "def gcd(a, b):\n",
312 " if b == 0:\n",
313 " return a\n",
314 " else:\n",
315 " return gcd(b, a%b)\n",
316 "\n",
317 "t0 = time.process_time()\n",
318 "print(gcd(155275387236018, 572335397352432))\n",
319 "t1 = time.process_time()\n",
320 "\n",
321 "print(\"Running time:\", t1-t0)"
322 ]
323 },
324 {
325 "cell_type": "markdown",
326 "metadata": {},
327 "source": [
328 "# Fibonacci numbers\n",
329 "\n",
330 "In the following cell there are two functions that compute the $n$-th Fibonacci number. They are almost the same, but the second one memorizes the results in a list to avoid computing them multiple times, and it is much much faster.\n",
331 "\n",
332 "Complexity: $O\\left(\\left(\\frac{1+\\sqrt 5}{2}\\right)^n\\right)\\sim O(1.6^n)$ for the slow version, $O(n)$ for the fast version."
333 ]
334 },
335 {
336 "cell_type": "code",
337 "execution_count": null,
338 "metadata": {},
339 "outputs": [],
340 "source": [
341 "import time\n",
342 "\n",
343 "F_memorized = [-1] * (10**6)\n",
344 "\n",
345 "def F_slow(n):\n",
346 " if n <= 1:\n",
347 " return n\n",
348 " else:\n",
349 " return F_slow(n-1) + F_slow(n-2)\n",
350 " \n",
351 "def F_fast(n):\n",
352 " if F_memorized[n] == -1:\n",
353 " if n <= 1:\n",
354 " F_memorized[n] = n\n",
355 " else:\n",
356 " F_memorized[n] = F_fast(n-1) + F_fast(n-2)\n",
357 " \n",
358 " return F_memorized[n]\n",
359 "\n",
360 "n = 40\n",
361 "\n",
362 "t0 = time.process_time()\n",
363 "print(F_slow(n))\n",
364 "t1 = time.process_time()\n",
365 "print(F_fast(n))\n",
366 "t2 = time.process_time()\n",
367 "\n",
368 "print(\"Time for F_slow:\", t1-t0)\n",
369 "print(\"Time for F_fast:\", t2-t1)"
370 ]
371 }
372 ],
373 "metadata": {
374 "kernelspec": {
375 "display_name": "Python 3",
376 "language": "python",
377 "name": "python3"
378 },
379 "language_info": {
380 "codemirror_mode": {
381 "name": "ipython",
382 "version": 3
383 },
384 "file_extension": ".py",
385 "mimetype": "text/x-python",
386 "name": "python",
387 "nbconvert_exporter": "python",
388 "pygments_lexer": "ipython3",
389 "version": "3.8.5"
390 }
391 },
392 "nbformat": 4,
393 "nbformat_minor": 4
394}

Generated with cgit - Back to sebastiano.tronto.net