├── .gitignore ├── Computer grathics └── Line drawing │ ├── Bresenham_float.py │ ├── Bresenham_int.py │ ├── Bresenham_smooth.py │ └── DDA.py ├── LICENSE ├── Number theoretic algorithms ├── Finding prime numbers │ ├── Sieve of Eratosthenes.py │ └── Trial division.py └── Primality tests │ └── Fermat.py ├── Numerical algorithms ├── Integrals │ ├── Left_rectangles.py │ ├── Middle_rectangles.py │ ├── Right_rectangles.py │ ├── Simpson38_method.py │ ├── Simpson_method.py │ └── Trapezium_method.py ├── Root finding │ ├── Bisection method.py │ ├── Finding roots.py │ ├── Fixed-point iteration method.py │ ├── Iterative method.py │ ├── Newton's method.py │ ├── Secant method.py │ ├── Simplified Newton's method.py │ ├── Сhords method.py │ └── Сombined method.py └── Solving system │ ├── gauss.py │ └── gauss_seidel.py ├── README.md └── Sorting algorithms ├── README.md ├── bubble sort.py ├── cocktail sort.py ├── comb sort.py ├── counting sort.py ├── gnome sort.py ├── insertion sort.py ├── iterative qsort.py ├── quick sort.py ├── selection sort.py └── shell sort.py /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | 3 | *.slo 4 | *.lo 5 | *.o 6 | *.a 7 | *.la 8 | *.lai 9 | *.so 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | 15 | /.qmake.cache 16 | /.qmake.stash 17 | *.pro.user 18 | *.pro.user.* 19 | *.qbs.user 20 | *.qbs.user.* 21 | *.moc 22 | moc_*.cpp 23 | qrc_*.cpp 24 | ui_*.h 25 | Makefile* 26 | *build-* 27 | 28 | # QtCreator 29 | 30 | *.autosave 31 | 32 | # QtCtreator Qml 33 | *.qmlproject.user 34 | *.qmlproject.user.* 35 | 36 | # QtCtreator CMake 37 | CMakeLists.txt.user 38 | 39 | -------------------------------------------------------------------------------- /Computer grathics/Line drawing/Bresenham_float.py: -------------------------------------------------------------------------------- 1 | def line_br_float(win, p1, p2): 2 | if p1 == p2: 3 | win.image.setPixel(p1[0], p1[1], win.pen.color().rgb()) 4 | return 5 | 6 | dx = p2[0] - p1[0] 7 | dy = p2[1] - p1[1] 8 | sx = sign(dx) 9 | sy = sign(dy) 10 | dx = abs(dx) 11 | dy = abs(dy) 12 | x = p1[0] 13 | y = p1[1] 14 | 15 | change = False 16 | 17 | if dy > dx: 18 | temp = dx 19 | dx = dy 20 | dy = temp 21 | change = True 22 | 23 | h = dy / dx 24 | 25 | e = h - 0.5 26 | i = 1 27 | while i <= dx: 28 | win.image.setPixel(x, y, win.pen.color().rgb()) 29 | if e >= 0: 30 | if change is False: 31 | y += sy 32 | else: 33 | x += sx 34 | e -= 1 35 | 36 | if e < 0: 37 | if change is False: 38 | x += sx 39 | else: 40 | y += sy 41 | e += h 42 | i+=1 -------------------------------------------------------------------------------- /Computer grathics/Line drawing/Bresenham_int.py: -------------------------------------------------------------------------------- 1 | def line_br_int(win, p1, p2): 2 | if p1 == p2: 3 | win.image.setPixel(p1[0], p1[1], win.pen.color().rgb()) 4 | return 5 | dx = p2[0] - p1[0] 6 | dy = p2[1] - p1[1] 7 | sx = sign(dx) 8 | sy = sign(dy) 9 | dx = abs(dx) 10 | dy = abs(dy) 11 | x = p1[0] 12 | y = p1[1] 13 | 14 | change = False 15 | 16 | if dy > dx: 17 | temp = dx 18 | dx = dy 19 | dy = temp 20 | change = True 21 | 22 | e = 2 * dy - dx 23 | i = 1 24 | while i <= dx: 25 | win.image.setPixel(x, y, win.pen.color().rgb()) 26 | if e >= 0: 27 | if change == 0: 28 | y += sy 29 | else: 30 | x += sx 31 | e -= 2 * dx 32 | 33 | if e < 0: 34 | if change == 0: 35 | x += sx 36 | else: 37 | y += sy 38 | e += (2 * dy) 39 | i += 1 40 | -------------------------------------------------------------------------------- /Computer grathics/Line drawing/Bresenham_smooth.py: -------------------------------------------------------------------------------- 1 | def line_br_smooth(win, p1, p2): 2 | if p1 == p2: 3 | win.image.setPixel(p1[0], p1[1], win.pen.color().rgb()) 4 | return 5 | 6 | win.pen.setColor(win.color_line) 7 | dx = p2[0] - p1[0] 8 | dy = p2[1] - p1[1] 9 | sx = sign(dx) 10 | sy = sign(dy) 11 | dx = abs(dx) 12 | dy = abs(dy) 13 | x = p1[0] 14 | y = p1[1] 15 | 16 | try: 17 | h = dy / dx 18 | except ZeroDivisionError: 19 | h = 0 20 | 21 | 22 | isBlack = False 23 | 24 | if win.pen.color() == Qt.black: 25 | i_max = 256 26 | isBlack = True 27 | else: 28 | i_max = 100 29 | 30 | change = False 31 | 32 | if dy > dx: 33 | temp = dx 34 | dx = dy 35 | dy = temp 36 | change = True 37 | if h: 38 | h = 1 / h 39 | 40 | h *= i_max 41 | e = i_max/2 42 | w = i_max - h 43 | i = 1 44 | while i <= dx: 45 | if not isBlack: 46 | new = win.pen.color() 47 | new.lighter(100 + e) 48 | win.pen.setColor(new) 49 | win.image.setPixel(x, y, win.pen.color().rgba()) 50 | else: 51 | new = QColor() 52 | new.setRgb(0, 0, 0, alpha=255 - e) 53 | win.pen.setColor(new) 54 | win.image.setPixel(x, y, win.pen.color().rgba()) 55 | if e <= w: 56 | if change: 57 | y += sy 58 | else: 59 | x += sx 60 | e += h 61 | else: 62 | x += sx 63 | y += sy 64 | e -= w 65 | i += 1 66 | -------------------------------------------------------------------------------- /Computer grathics/Line drawing/DDA.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def sign(x): 4 | if x > 0: 5 | return 1 6 | elif x < 0: 7 | return -1 8 | else: 9 | return 0 10 | 11 | 12 | def line_DDA(win, p1, p2): 13 | # Длина и высота линии 14 | deltaX = abs(p1[0] - p2[0]) 15 | deltaY = abs(p1[1] - p2[1]) 16 | 17 | # Считаем минимальное количество итераций, необходимое для отрисовки отрезка. 18 | # Выбирая максимум из длины и высоты линии, обеспечиваем связность линии 19 | 20 | length = max(deltaX, deltaY) 21 | 22 | # особый случай, на экране закрашивается ровно один пиксел 23 | if length == 0: 24 | win.image.setPixel(p1[0], p1[1], win.pen.color().rgb()) 25 | return 26 | 27 | # Вычисляем приращения на каждом шаге по осям абсцисс и ординат double 28 | dX = (p2[0] - p1[0]) / length 29 | dY = (p2[1] - p1[0]) / length 30 | 31 | # Начальные значения 32 | x = p1[0] + 0.5 * sign(dX) 33 | y = p1[1] + 0.5 * sign(dY) 34 | 35 | # Основной цикл 36 | while length > 0: 37 | win.image.setPixel(x, y, win.pen.color().rgb()) 38 | x += dX 39 | y += dY 40 | length -= 1 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Pandas 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Number theoretic algorithms/Finding prime numbers/Sieve of Eratosthenes.py: -------------------------------------------------------------------------------- 1 | n = int(input("Input the upper bound: ")) 2 | 3 | a = list(range(n+1)) 4 | 5 | a[1] = 0 6 | 7 | lst = [] 8 | 9 | i = 2 10 | while i <= n: 11 | if a[i] != 0: 12 | lst.append(a[i]) 13 | for j in range(i, n+1, i): 14 | a[j] = 0 15 | i += 1 16 | 17 | print("The prime numbers are ...", lst) -------------------------------------------------------------------------------- /Number theoretic algorithms/Finding prime numbers/Trial division.py: -------------------------------------------------------------------------------- 1 | n = int(input("Input the upper bound: ")) 2 | 3 | lst = [2] # list with prime numbers 4 | 5 | for i in range(3, n + 1, 2): 6 | if (i > 10) and (i % 10 == 5): 7 | continue 8 | for j in lst: 9 | if j * j - 1 > i: 10 | lst.append(i) 11 | break 12 | if i % j == 0: 13 | break 14 | else: 15 | lst.append(i) 16 | 17 | print("The prime numbers are ...", lst) 18 | -------------------------------------------------------------------------------- /Number theoretic algorithms/Primality tests/Fermat.py: -------------------------------------------------------------------------------- 1 | # Beware of Carmichael numbers 2 | import random 3 | import time 4 | 5 | random.seed() 6 | 7 | k = 0 8 | level_of_security = 128 # 2^-128 9 | 10 | 11 | def std_is_prime(x): 12 | global k 13 | 14 | lvl = k 15 | if x == 2: 16 | return True 17 | while lvl < level_of_security: 18 | 19 | rnd = random.randint(1, x - 1) 20 | 21 | if (rnd ** (x - 1) % x != 1): 22 | return False 23 | 24 | lvl += 1 25 | 26 | return True 27 | 28 | 29 | def opt_is_prime(x): 30 | global k 31 | 32 | lvl = k 33 | if x == 2: 34 | return True 35 | while lvl < level_of_security: 36 | rnd = random.randint(1, x - 1) 37 | if gcd(rnd, x) != 1: 38 | return False 39 | if pows(rnd, x - 1, x) != 1: 40 | return False 41 | 42 | lvl += 1 43 | 44 | return True 45 | 46 | 47 | def gcd(a, b): # Euclidean algorithm 48 | if not b: 49 | return a 50 | 51 | return gcd(b, a % b) 52 | 53 | 54 | def mul(a, b, mod): # Binary mul with mod 55 | if b == 1: 56 | return a 57 | if not b % 2: 58 | t = mul(a, b / 2, mod) 59 | return (2 * t) % mod 60 | 61 | return (mul(a, b - 1, mod) + a) % mod 62 | 63 | 64 | def pows(a, b, mod): # Binary pow with mod 65 | if b == 0: 66 | return 1 67 | if not b % 2: 68 | t = pows(a, b / 2, mod) 69 | return mul(t, t, mod) % mod 70 | 71 | return (mul(pows(a, b-1, mod), a, mod)) % mod 72 | 73 | 74 | if __name__ == "__main__": 75 | test_set = [2, 11, 7, 561, 23, 199, 3539, 8, 150, 4045, 2663] 76 | p = 17471 77 | 78 | print("...NOT OPTIMAZED...") 79 | 80 | for t in test_set: 81 | print("Is {0} prime? ->".format(t), std_is_prime(t)) 82 | 83 | st = time.time() 84 | res = std_is_prime(p) 85 | end = time.time() 86 | if res: 87 | print("Found the prime number was detected for ", end - st, " sec") 88 | else: 89 | print("Test crached!") 90 | 91 | print("\n\n...OPTIMAZED...") 92 | 93 | for t in test_set: 94 | print("Is {0} prime? ->".format(t), opt_is_prime(t)) 95 | 96 | st = time.time() 97 | res = opt_is_prime(p) 98 | end = time.time() 99 | if res: 100 | print("Found the prime number was detected for ", end - st, " sec") 101 | else: 102 | print("Test crached!") -------------------------------------------------------------------------------- /Numerical algorithms/Integrals/Left_rectangles.py: -------------------------------------------------------------------------------- 1 | def f(x): 2 | return x**x 3 | 4 | def left(a,b,n): 5 | h = abs(b-a)/n 6 | S = 0 7 | while fabs(a-b)>0.0001: 8 | S += f(a) 9 | a += h 10 | return S*h -------------------------------------------------------------------------------- /Numerical algorithms/Integrals/Middle_rectangles.py: -------------------------------------------------------------------------------- 1 | def f(x): 2 | return x**x 3 | 4 | def centr(a,b,n): 5 | h = abs(b-a)/n 6 | S = 0 7 | while fabs(a-b)>0.0001: 8 | S += f((2*a+h)/2) 9 | a += h 10 | return S*h -------------------------------------------------------------------------------- /Numerical algorithms/Integrals/Right_rectangles.py: -------------------------------------------------------------------------------- 1 | def f(x): 2 | return x**x 3 | 4 | def right(a,b,n): 5 | h = abs(b-a)/n 6 | S = 0 7 | while fabs(a-b)>0.0001: 8 | a += h 9 | S += f(a) 10 | return S*h 11 | -------------------------------------------------------------------------------- /Numerical algorithms/Integrals/Simpson38_method.py: -------------------------------------------------------------------------------- 1 | def f(x): 2 | return x**x 3 | 4 | 5 | def simpson38 (a,b,n): 6 | h = abs(b-a)/n 7 | S = 0 8 | while a-b<-h/2: 9 | S += f(a)+3*f(a+h/3)+3*f(a+2*h/3)+f(a+h) 10 | a += h 11 | return S*h/8 -------------------------------------------------------------------------------- /Numerical algorithms/Integrals/Simpson_method.py: -------------------------------------------------------------------------------- 1 | def simpson(func, *args, right, left, n): 2 | h = (right - left) / n 3 | 4 | ans = h / 3 5 | even = 0.0 6 | odd = 0.0 7 | 8 | for i in range(1, n): 9 | if i % 2 == 0: 10 | even += func(left + h * i, *args) 11 | else: 12 | odd += func(left + h * i, *args) 13 | 14 | ans *= (2 * even + 4 * odd + func(left, *args) + func(right, *args)) 15 | return ans 16 | -------------------------------------------------------------------------------- /Numerical algorithms/Integrals/Trapezium_method.py: -------------------------------------------------------------------------------- 1 | def f(x): 2 | return x**x 3 | 4 | 5 | def trap(a,b,n): 6 | h = abs(b-a)/n 7 | S = 0 8 | while fabs(a-b)>0.0001: 9 | S += (f(a)+f(a+h))/2 10 | a += h 11 | return S*h -------------------------------------------------------------------------------- /Numerical algorithms/Root finding/Bisection method.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | def f(x): 5 | return np.sin(x) 6 | def p(x): 7 | return np.cos(x) 8 | 9 | a = -10 10 | b = 10 11 | h = 1 12 | points = [] 13 | eps = 0.001 14 | 15 | n = 0 16 | b1 = a 17 | a1 = a 18 | for i in range(int((b - a)//h)): 19 | b1 += h 20 | a1 = b1 - h 21 | if b1 != 0: 22 | if f(a1) * f(b1) <= 0: 23 | xstart = a1 24 | xend = b1 25 | while abs(abs(xstart)-abs(xend)) >= eps: 26 | c = (xend + xstart)/2 27 | if f(xstart)*f(c) <= 0: 28 | xend = c 29 | else: 30 | xstart = c 31 | n += 1 32 | points.append(c) 33 | print(n,'=',c) 34 | 35 | 36 | plt.figure('Добрый день') 37 | points = np.array(points) 38 | x1 = np.linspace(a,b,1000) 39 | plt.plot(x1,f(x1),color='g', linewidth=1.0) 40 | plt.plot(points,f(points),'ro') 41 | plt.subplot(111).spines['bottom'].set_position('zero') 42 | plt.title('$Kulish$') 43 | plt.ylabel('$y=sin(x)$') 44 | plt.grid(True) 45 | plt.show() 46 | 47 | -------------------------------------------------------------------------------- /Numerical algorithms/Root finding/Finding roots.py: -------------------------------------------------------------------------------- 1 | from math import sin, cos 2 | def f(x): 3 | return cos(x) 4 | 5 | def fd(x): 6 | return -sin(x) 7 | 8 | def fdd(x): 9 | return -cos(x) 10 | 11 | # норм 12 | def half(a, b, eps): 13 | c = (a + b) / 2 14 | if f(c) == 0: 15 | return c 16 | if f(a) == 0: 17 | return a 18 | if f(b) == 0: 19 | return b 20 | while (b - a) >= eps: 21 | if f(a) * f(c) <= 0: 22 | b = c 23 | else: 24 | a = c 25 | c = (a + b) / 2 26 | return c 27 | 28 | # норм 29 | def newton(a, b, eps): 30 | if f(a) == 0: 31 | return a 32 | if f(b) == 0: 33 | return b 34 | while abs(b - a) >= eps: 35 | a = b - f(b)/ fd(b) 36 | b = a - f(a)/fd(a) 37 | return (b + a)/2 38 | 39 | 40 | # норм 41 | def newton_imp(a, b, eps): 42 | if f(a) == 0: 43 | return a 44 | if f(b) == 0: 45 | return b 46 | if f(a) * fdd(a) > 0: 47 | fix = fd(a) 48 | else: 49 | fix = fd(b) 50 | while abs(b - a) >= eps: 51 | a = b - f(b)/ fix 52 | b = a - f(a)/ fix 53 | return a 54 | 55 | # норм 56 | def chord(a, b, eps): 57 | if f(a) == 0: 58 | return a 59 | if f(b) == 0: 60 | return b 61 | if f(a) * fdd(a) > 0: 62 | fix = a 63 | x = b 64 | h = ((x - fix) * f(x)) /(f(x) - f(fix)) 65 | else: 66 | fix = b 67 | x = a 68 | h = ((x - fix) * f(x)) /(f(x) - f(fix)) 69 | while abs(h) >= eps: 70 | x -= h 71 | h = ((x - fix) * f(x)) /(f(x) - f(fix)) 72 | return x 73 | 74 | 75 | 76 | 77 | # норм 78 | def tan(a, b, eps): 79 | if f(a) == 0: 80 | return a 81 | if f(b) == 0: 82 | return b 83 | while abs(b - a) >= eps: 84 | a = b - f(b) * (a - b)/(f(a) - f(b)) 85 | b = a - f(a) * (b - a)/(f(b) - f(a)) 86 | return b 87 | 88 | def comb(a, b, eps): 89 | if f(a) == 0: 90 | return a 91 | if f(b) == 0: 92 | return b 93 | while abs(a - b) >= eps: 94 | if f(a) * fdd(a) < 0: 95 | a -= (f(a) * (a - b))/(f(a) - f(b)) 96 | else: 97 | a -= f(a)/fd(a) 98 | if f(b) * fdd(b) < 0: 99 | b -= (f(b) * (b - a))/(f(b) - f(a)) 100 | else: 101 | b -= f(b)/fd(b) 102 | return (a + b)/2 103 | 104 | def steffenson(a, b, eps): 105 | try: 106 | while abs(b - a) > eps and n >= 0: 107 | c = a - f(a)**2/(f(a + f(a)) - f(a)) 108 | b = c 109 | a = (a+c)/2 110 | return c 111 | except: 112 | return '-' 113 | 114 | 115 | def iteration(a, b, eps): 116 | for x0 in [a,b]: 117 | 118 | #подбираем lambd 119 | #lmbd == false => lambda = 1 120 | #lmbd == true => lambda = 1/fp(x) 121 | lmbd = False 122 | x1 = x0 - f(x0) 123 | x2 = x1 - f(x1) 124 | 125 | if abs(x2 - x1) > abs(x1 - x0): 126 | lmbd = True 127 | if (fd(x1) == 0) or (fd(x0) == 0) : 128 | return x1 129 | x1 = x0 - f(x0)/fd(x0) 130 | x2 = x1 - f(x1)/fd(x1) 131 | if abs(x2 - x1) > abs(x1 - x0): 132 | return x1 133 | 134 | while True: 135 | 136 | if not lmbd: 137 | x1 = x0 - f(x0) 138 | else: 139 | x1 = x0 - f(x0)/fd(x0) 140 | #условия завершения 141 | if eps > 0: 142 | if abs(x1 - x0) < eps: 143 | return x1 144 | 145 | 146 | def plotting1(key): 147 | global list_of_roots 148 | m = np.linspace(a, b, 1000) 149 | y = [] 150 | z = [] 151 | u = [] 152 | for k in range(len(m)): 153 | y.append(f(m[k], key)) 154 | z.append(f(m[k], 4)) 155 | u.append(f(m[k], 5)) 156 | for k in range(len(list_of_roots)): 157 | if k == 0: 158 | plt.scatter(list_of_roots[k], f(list_of_roots[k], key), marker='o', color='r', label='Roots') 159 | else: 160 | plt.scatter(list_of_roots[k], f(list_of_roots[k], key), marker='o', color='r') 161 | for k in range(len(ext)): 162 | if k == 0: 163 | plt.scatter(ext[k], f(ext[k], 0), marker='s', color='m', label='Extrema') 164 | else: 165 | plt.scatter(ext[k], f(ext[k], 0), marker='s', color='m') 166 | for k in range(len(bend)): 167 | if k == 0: 168 | plt.scatter(bend[k], f(bend[k], 0), marker='p', color='orange', label='Inflection') 169 | else: 170 | plt.scatter(bend[k], f(bend[k], 0), marker='p', color='orange') 171 | plt.plot(m, y, color='k', linewidth=1.0, label='x*sin(x) ') 172 | plt.plot(m, z, color='g', alpha=0.5, linewidth=1.0, label='The first derivative') 173 | plt.plot(m, u, color='pink', alpha=0.5, linewidth=1.0, label='The second derivative') 174 | plt.grid(True, color='b', linewidth=0.5) 175 | plt.axis([a, b, -15., 15.]) 176 | plt.ylabel('f(x)', size=14) 177 | plt.xlabel('x', size=14) 178 | plt.legend(frameon=False) 179 | plt.title('The function, its the first and the second \nderivatives with points of inflection and extrema') 180 | plt.show() 181 | 182 | 183 | 184 | v = 5 185 | w = 7 186 | ep = 0.0001 187 | print('половинного ', half(v, w, ep)) 188 | print('касательные ', newton(v, w, ep)) 189 | print('имп касательные ', newton_imp(v, w, ep)) 190 | print('хорды ',chord(v, w, ep)) 191 | print('сек ', tan(v, w, ep)) 192 | print('комб ', comb(v, w, ep)) 193 | print('стеффенсон ', steffenson(6, 7, ep)) 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | -------------------------------------------------------------------------------- /Numerical algorithms/Root finding/Fixed-point iteration method.py: -------------------------------------------------------------------------------- 1 | from math import sin, cos, e 2 | import matplotlib.pyplot as plt 3 | import numpy as np 4 | 5 | 6 | def f(x): 7 | return x**2-2 8 | def fp(x): 9 | return 2*x 10 | 11 | def iterationMethod(a, b, f, fp, eps_x, eps_y, max_n): 12 | #третий аргумент return - false , если корень не найден 13 | n = 0 14 | for x0 in [a,b]: 15 | 16 | #подбираем lambd 17 | #lmbd == false => lambda = 1 18 | #lmbd == true => lambda = 1/fp(x) 19 | lmbd = False 20 | x1 = x0 - f(x0) 21 | x2 = x1 - f(x1) 22 | 23 | if abs(x2 - x1) > abs(x1 - x0): 24 | lmbd = True 25 | if (fp(x1) == 0) or (fp(x0) == 0) : 26 | return x1, n, False 27 | x1 = x0 - f(x0)/fp(x0) 28 | x2 = x1 - f(x1)/fp(x1) 29 | if abs(x2 - x1) > abs(x1 - x0): 30 | return x1, n, False 31 | 32 | while True: 33 | n += 1 34 | 35 | if not lmbd: 36 | x1 = x0 - f(x0) 37 | else: 38 | x1 = x0 - f(x0)/fp(x0) 39 | #условия завершения 40 | if eps_x > 0: 41 | if abs(x1 - x0) < eps_x: 42 | return x1, n, True 43 | if eps_y > 0: 44 | if abs(f(x1) - f(x0)) < eps_y: 45 | return x1, n, True 46 | if n >= max_n: 47 | return x1, n, True 48 | if not (a<=x1<=b): 49 | #если произошел выход за границы 50 | #обычно срабатывает при отстутсвии корня 51 | break 52 | 53 | x0 = x1 54 | 55 | #если не найдено корней, то 56 | return x1, n, False 57 | 58 | 59 | 60 | def generateRootsData(a, b, h, eps_x, eps_y, max_n): 61 | ah = a 62 | bh = a + h 63 | roots_data = [] 64 | step = 1 65 | while bh <= b: 66 | x, n, finded = iterationMethod(ah, bh, f, fp, eps_x, eps_y, max_n) 67 | if finded: 68 | left_border = ah 69 | right_border = bh 70 | root = x 71 | value = f(x) 72 | iteration_n = n 73 | if n >= max_n: 74 | err_code = 1 75 | else: 76 | err_code = 0 77 | if not x in [i[2] for i in roots_data]: 78 | roots_data.append([left_border, right_border, root, value, iteration_n, err_code]) 79 | 80 | step += 1 81 | ah = a + h * (step - 1) 82 | bh = a + h * step 83 | if bh > b: 84 | if ah > b: 85 | break 86 | else: 87 | bh = b 88 | return roots_data 89 | 90 | def inputData(): 91 | inp = input('Введите интервал поиска [A,B] в формате "A,B": ') 92 | a,b = map(float, inp.split(',')) 93 | inp = input('Введите шаг h: ') 94 | h = float(inp) 95 | inp = input('Введите ? по x, если требуется: ') 96 | if inp.strip() == '': 97 | eps_x = 0 98 | else: 99 | eps_x = float(inp) 100 | inp = input('Введите ? по y, если требуется: ') 101 | if inp.strip() == '': 102 | eps_y = 0 103 | else: 104 | eps_y = float(inp) 105 | inp = input('Введите предельное число итераций n_max >= 100: ') 106 | max_n = int(inp) 107 | if not (max_n>=100): 108 | print('Неверный ввод!') 109 | return 0 110 | return a, b, h, eps_x, eps_y, max_n 111 | 112 | 113 | def printTable(data, max_n): 114 | # расчет форматированной строки 115 | maxalen = len( str(data[-1][0]) + str(data[-1][1]) ) 116 | abrowlen = maxalen + 5 117 | iterrowlen = len('кол-во итераций') + 2 118 | errrowlen = len('код ошибки') + 2 119 | table_width = (1 + 9 + 1 + abrowlen + 1 120 | + 14 + 1 + 15 + 1 + iterrowlen + 1 + errrowlen+1) 121 | t_row = ('|{:^9}|{:^'+str(abrowlen)+'}|{:^14}|{:^15}|{:^'+str(iterrowlen) 122 | +'}|{:^'+str(errrowlen)+'}|') 123 | t_head = t_row.format('№ корня','[А,B]','корень','f(x)','кол-во итераций', 124 | 'код ошибки') 125 | 126 | print('-'*table_width) 127 | print(t_head) 128 | print('|','-'*(table_width-2),'|', sep='') 129 | n = 0 130 | for i in data: 131 | n += 1 132 | arg1 = n 133 | arg2 = ('['+'{:g}'.format(i[0])+',' 134 | +'{:g}'.format(i[1])+']') 135 | arg3 = '{:g}'.format(i[2]) 136 | arg4 = '{:.0e}'.format(i[3]) 137 | arg5 = i[4] 138 | arg6 = i[5] 139 | if arg6 != 0: 140 | arg3 = arg4 = '-' 141 | print(t_row.format(arg1, arg2, arg3, arg4, arg5, arg6 )) 142 | print('-'*table_width) 143 | 144 | print('Коды ошибок: ') 145 | print('0 - нет ошибки') 146 | print('1 - достигнуто максимальное количество итераций') 147 | 148 | 149 | 150 | def drawPlot(data, a, b): 151 | x_f = np.linspace(a,b, 1000) 152 | y_f = list(map(f, x_f)) 153 | x_roots = [] 154 | y_roots = [] 155 | point_text = [] 156 | for row in range(len(data)): 157 | if data[row][5] == 0: 158 | x_roots.append(data[row][2]) 159 | y_roots.append(data[row][3]) 160 | point_text.append(row+1) 161 | 162 | bottom = min(y_f) 163 | top = max(y_f) 164 | if bottom > 0: 165 | bottom*=0.9 166 | elif bottom < 0: 167 | bottom*=1.1 168 | #else: 169 | # bottom = -top * 0.1 170 | if top > 0: 171 | top*=1.1 172 | elif top < 0: 173 | top*=0.9 174 | #else: 175 | # top = -bottom * 0.1 176 | 177 | 178 | ax = plt.subplot() 179 | 180 | plt.axis([a,b, bottom, top]) 181 | plt.title('Finding roots of f(x) with fixed-point iteration method') 182 | plt.xlabel('x') 183 | plt.ylabel('f(x)') 184 | 185 | plt.plot(x_f,y_f, '-', color='blue', label='f(x)') 186 | plt.plot(x_roots, y_roots, 'bo', color='red', label = 'finded roots') 187 | 188 | for i in range(len(x_roots)): 189 | ax.annotate('#'+str(point_text[i]), (x_roots[i],y_roots[i])) 190 | plt.legend() 191 | 192 | plt.plot([a,b], [0,0], '-', color='black') 193 | plt.plot([0,0], [bottom,top], '-', color='black') 194 | 195 | plt.show() 196 | 197 | 198 | def main(): 199 | while 1: 200 | print('=== Уточнение корня методом подбора с итерацией ===') 201 | #ввод данных 202 | inp_data = inputData() 203 | if inp_data == 0: 204 | return 205 | else: 206 | a, b, h, eps_x, eps_y, max_n = inp_data 207 | 208 | #генерация и вывод таблицы 209 | print() 210 | print(' - поиск корней - ') 211 | roots_data = generateRootsData(a, b, h, eps_x, eps_y, max_n) 212 | if len(roots_data) == 0: 213 | print('Корней не найдено!') 214 | else: 215 | printTable(roots_data, max_n) 216 | drawPlot(roots_data, a, b) 217 | 218 | 219 | #просьба еще одного ввода 220 | print() 221 | inp = input('Введите 1, чтобы ввести новые данные: ') 222 | if inp!='1': 223 | break 224 | else: 225 | print() 226 | print() 227 | 228 | 229 | 230 | main() 231 | 232 | -------------------------------------------------------------------------------- /Numerical algorithms/Root finding/Iterative method.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | def f(x): 5 | return x*x-9 6 | def p(x): 7 | return np.cos(x) 8 | 9 | a = -10 10 | b = 10 11 | h = 1 12 | points = [] 13 | eps = 0.001 14 | 15 | n = 0 16 | b1 = a 17 | a1 = a 18 | for i in range(int((b - a)//h)): 19 | b1 += h 20 | a1 = b1 - h 21 | if f(a1) * f(b1) <= 0: 22 | xstart = a1 23 | xend = b1 24 | if b1 != 0: 25 | while abs(abs(xstart)-abs(xend)) >= eps: 26 | k = f(xstart+f(xstart))-f(xstart) 27 | if k == 0: 28 | xp = 0 29 | else: 30 | xp = xstart - f(xstart)*f(xstart)/k 31 | xstart,xend = xp,xstart 32 | n += 1 33 | points.append(xp) 34 | print(n,'=',xp) 35 | 36 | 37 | plt.figure('Добрый день') 38 | points = np.array(points) 39 | x1 = np.linspace(a,b,1000) 40 | plt.plot(x1,f(x1),color='g', linewidth=1.0) 41 | plt.plot(points,f(points),'ro') 42 | plt.subplot(111).spines['bottom'].set_position('zero') 43 | plt.title('$Kulish$') 44 | plt.ylabel('$y=sin(x)$') 45 | plt.grid(True) 46 | plt.show() 47 | 48 | -------------------------------------------------------------------------------- /Numerical algorithms/Root finding/Newton's method.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | def f(x): 5 | return np.sin(x) 6 | def p(x): 7 | return np.cos(x) 8 | 9 | a,b,h=map(float,input('Введите границы и шаг.(через запятую): ').split(',')) 10 | n=int(input('Введите макс количество итераций: ')) 11 | points = [] 12 | eps=float(input('Введите точность: ')) 13 | 14 | n = 0 15 | b1 = a 16 | a1 = a 17 | for i in range(int((b - a)//h)): 18 | b1 += h 19 | a1 = b1 - h 20 | if b1 != 0: 21 | if f(a1) * f(b1) <= 0: 22 | xstart = a1 23 | xend = b1 24 | while abs(abs(xstart)-abs(xend)) >= eps: 25 | xp = xstart - f(xstart)/p(xstart) 26 | xstart,xend = xp,xstart 27 | n += 1 28 | points.append(xp) 29 | print(n,'=',xp) 30 | 31 | 32 | plt.figure('Добрый день') 33 | points = np.array(points) 34 | x1 = np.linspace(a,b,1000) 35 | plt.plot(x1,f(x1),color='g', linewidth=1.0) 36 | plt.plot(points,f(points),'ro') 37 | plt.subplot(111).spines['bottom'].set_position('zero') 38 | plt.title('$Kuznetsov$') 39 | plt.ylabel('$y=sin(x)$') 40 | plt.grid(True) 41 | plt.show() 42 | 43 | -------------------------------------------------------------------------------- /Numerical algorithms/Root finding/Secant method.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | from math import * 4 | points = [] 5 | p = 0 6 | 7 | # Ввод: 8 | print('Введите начало и конец отрезка, через пробел:',end = ' ') 9 | a, b = map(float, input().split(' ')) 10 | n = int(input('Введите кол-во итераций: ')) 11 | eps_x = float(input('Введите eps по х: ')) 12 | eps_y = float(input('Введите eps по y: ')) 13 | h = float(input('Введите шаг: ')) 14 | 15 | 16 | # Табличка: 17 | def W(): 18 | print(''' 19 | Справка: 20 | 0 - ошибок допущено не было 21 | 1 - превышение количества итераций 22 | n - число итераций''') 23 | print('\n№ Корня | A | B | Корень | f(x) |\ 24 | n | Код ошибки') 25 | 26 | 27 | # Функция: 28 | def f(x): 29 | #f = np.sin(x)*x#x*x - x - 2 30 | f = np.sin(x) 31 | return f 32 | 33 | # Вычисление способом секущих: 34 | W() 35 | b1 = a 36 | a1 = a 37 | m, it = 0, 0 38 | if h == 3: 39 | h -= 1 40 | p = 1 41 | 42 | def s(u): 43 | if f(2) == sin(2) and u != 0: 44 | u *= 1.5 45 | return u 46 | for i in range(int((b - a)//h)): 47 | b1 += h 48 | a1 = b1 - h 49 | if b1 != 0: 50 | if f(a1) * f(b1) <= 0: 51 | xstart = a1 52 | xend = b1 53 | while abs(abs(xstart)-abs(xend)) >= eps_x or abs(abs(f(xstart))-abs(f(xend))) >= eps_y: 54 | xp = xstart - f(xstart)*(xend - xstart)/(f(xend)-f(xstart)) 55 | xstart, xend = xp, xstart 56 | it += 1 57 | points.append(xp) 58 | m += 1 59 | if p == 1: 60 | print('{:^8}|{:^5.1f}|{:^5.1f}|'. format(m,s(a1),s(b1)),sep = '|',end='') 61 | else: 62 | print('{:^8}|{:^5.1f}|{:^5.1f}|'. format(m,a1,b1),sep = '|',end='') 63 | if it > n: 64 | code = '1' 65 | print('{:^10}|{:^10}|{:^5}|\ 66 | {:^10}'. format('---','---',it,code),sep = '|') 67 | else: 68 | code = '0' 69 | print('{:^10.5f}|{:^10.6f}|\ 70 | {:^5}|{:^10}'. format(xp,f(xp),it,code),sep = '|') 71 | 72 | # График: 73 | points = np.array(points) 74 | x1 = np.linspace(a,b,1000) 75 | x = np.arange(f(a), f(b+h), h) 76 | plt.figure(1) 77 | plt.plot(x1,f(x1),color='y', linewidth=2.0) 78 | plt.plot(points ,f(points),'go') 79 | plt.grid(True) 80 | plt.title('$Kulish$') 81 | plt.ylabel('$y=f(x)$') 82 | plt.subplot(111).spines['bottom'].set_position('zero') 83 | print('\n',' '*20,'Enter=Пуск!',end='') 84 | i = input() 85 | plt.show() 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /Numerical algorithms/Root finding/Simplified Newton's method.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | def f(x): 5 | return np.sin(x) 6 | def p(x): 7 | return np.cos(x) 8 | 9 | a = -10 10 | b = 10 11 | h = 1 12 | points = [] 13 | eps = 0.001 14 | 15 | n = 0 16 | b1 = a 17 | a1 = a 18 | for i in range(int((b - a)//h)): 19 | b1 += h 20 | a1 = b1 - h 21 | if b1 != 0: 22 | if f(a1) * f(b1) <= 0: 23 | xstart = a1 24 | xend = b1 25 | while abs(abs(xstart)-abs(xend)) >= eps: 26 | xp = xstart - f(xstart)/p(a1) 27 | xstart,xend = xp,xstart 28 | n += 1 29 | points.append(xp) 30 | print(n,'=',xp) 31 | 32 | 33 | plt.figure('Добрый день') 34 | points = np.array(points) 35 | x1 = np.linspace(a,b,1000) 36 | plt.plot(x1,f(x1),color='g', linewidth=1.0) 37 | plt.plot(points,f(points),'ro') 38 | plt.subplot(111).spines['bottom'].set_position('zero') 39 | plt.title('$Kuznetsov$') 40 | plt.ylabel('$y=sin(x)$') 41 | plt.grid(True) 42 | plt.show() 43 | 44 | -------------------------------------------------------------------------------- /Numerical algorithms/Root finding/Сhords method.py: -------------------------------------------------------------------------------- 1 | from math import sin 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | def f(x): 6 | return np.sin(x) 7 | 8 | def horda(x1, x2, E, Nconst): 9 | t1 = x2 10 | t2 = x1 11 | N = 0 12 | while abs(t1 - t2) > E and N <= Nconst: 13 | if N != 0: 14 | t1 = t2 15 | N += 1 16 | t2 = t1 - (f(t1)/(f(t1) - f(x1)))*(t1 - x1) 17 | return t1, N , 0 18 | 19 | def hordb(x1, x2, E, Nconst): 20 | t1 = x1 21 | t2 = x2 22 | N = 0 23 | while abs(t1 - t2) > E and N <= Nconst: 24 | if N != 0: 25 | t1 = t2 26 | N += 1 27 | t2 = t1 - f(t1)*(x2 - t1)/(f(x2) - f(t1)) 28 | return t1, N , 0 29 | 30 | a = float(input('Введите первую границу: ')) 31 | b = float(input('Введите вторую границу; ')) 32 | h = float(input('введите шаг: ')) 33 | E = float(input('Введите точность: ')) 34 | Nconst = int(input('Введите максимальное число итераций: ')) 35 | 36 | T = [] 37 | 38 | # n - номер корня 39 | n = 0 40 | x = a - h 41 | d = b - a 42 | 43 | if ((d)/h)%1 != 0: 44 | r = int((d)/h) + 1 45 | else: 46 | r = int((d)/h) 47 | 48 | for i in range(r): 49 | x += h 50 | if i == r - 1: 51 | h = int(d) - h*(r - 1) 52 | N = 0 # N - число итераций 53 | if abs(f(x)) < E: 54 | if x == a: 55 | n += 1 56 | k = x 57 | t = [n, x, x + h, k, N, 1] 58 | T.append(t) 59 | elif abs(f(x + h)) < E: 60 | n += 1 61 | k = x + h 62 | t = [n, x, x + h, k, N, 1] 63 | T.append(t) 64 | else: 65 | 66 | if f(x)/abs(f(x)) != f(x + h)/abs(f(x + h)): 67 | qk = (f(x) - f(x + h))/(-h) 68 | qb = (x*f(x + h) - (x + h)*f(x))/(-h) 69 | x0 = (-qb)/qk 70 | 71 | if f(x) > f(x + h): 72 | if f(x0) <= 0: 73 | k, N, ko = horda(x, x + h, E, Nconst) 74 | 75 | elif f(x0) > 0: 76 | k, N, ko = hordb(x, x + h, E, Nconst) 77 | 78 | elif f(x) < f(x + h): 79 | if f(x0) <= 0: 80 | k, N, ko = hordb(x, x + h, E, Nconst) 81 | 82 | elif f(x0) > 0: 83 | k, N, ko = horda(x, x + h, E, Nconst) 84 | 85 | n += 1 86 | t = [n, x, x + h, k, N, ko] 87 | T.append(t) 88 | 89 | # Вывод результатов 90 | print() 91 | if T == []: 92 | print('Корней нет.') 93 | 94 | else: 95 | print('N - номер корня A B Корень ', end = '') 96 | print('Число итераций Код ошибки') 97 | 98 | for i in range(len(T)): 99 | n = T[i][0] 100 | A = T[i][1] 101 | B = T[i][2] 102 | k = T[i][3] 103 | N = T[i][4] 104 | ko = T[i][5] 105 | 106 | print('{:6d}{:17.3f}{:10.3f}'.format(n, A, B), end = '') 107 | 108 | if k == int(k): 109 | k = int(k) 110 | 111 | print('{:11d}'.format(k), end = ' '*6) 112 | print('{:13d}{:17d}'.format(N, ko)) 113 | 114 | elif 0 < abs(int(k)) < 10: 115 | print('{:15.6f}'.format(k), end = ' '*6) 116 | print('{:9d}{:17d}'.format(N, ko)) 117 | 118 | else: 119 | print('{:17.6e}'.format(k), end = '') 120 | print('{:13d}{:17d}'.format(N, ko)) 121 | 122 | print() 123 | print() 124 | print('"Код ошибки" \n') 125 | 126 | print('0 - программа в полной мере выполняет свою', end = ' ') 127 | print('функцию (метод хорд применяется). \n') 128 | 129 | print('1 - значение корня совпало с одним из крайних значений') 130 | print('отрезка [A, B] (метод хорд не применяется).') 131 | 132 | k = [0, 0] 133 | x = np.linspace(a, b, 100) 134 | plt.plot(x, f(x), 'g') 135 | if T != []: 136 | for i in range(len(T)): 137 | plt.plot(T[i][3], 0, 'yo', markersize = 8) 138 | plt.title('$Kuznetsov$') 139 | plt.ylabel('$f(x)$') 140 | plt.subplot(111).spines['bottom'].set_position('zero') 141 | plt.grid(True) 142 | plt.show() 143 | -------------------------------------------------------------------------------- /Numerical algorithms/Root finding/Сombined method.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | def f(x): 5 | return np.sin(x) 6 | def p(x): 7 | return np.cos(x) 8 | 9 | a = -10 10 | b = 10 11 | h = 1 12 | points = [] 13 | eps = 0.001 14 | 15 | n = 0 16 | b1 = a 17 | a1 = a 18 | for i in range(int((b - a)//h)): 19 | b1 += h 20 | a1 = b1 - h 21 | if b1 != 0: 22 | if f(a1) * f(b1) <= 0: 23 | xstart = a1 24 | xend = b1 25 | while abs(abs(xstart)-abs(xend)) >= eps: 26 | xp = xend - f(xend)*(xstart-xend)/(f(xstart)-f(xend)) 27 | xend -= f(xend)/p(xend) 28 | xstart,xend = xp,xstart 29 | n += 1 30 | points.append(xp) 31 | print(n,'=',xp) 32 | 33 | 34 | plt.figure('Добрый день') 35 | points = np.array(points) 36 | x1 = np.linspace(a,b,1000) 37 | plt.plot(x1,f(x1),color='g', linewidth=1.0) 38 | plt.plot(points,f(points),'ro') 39 | plt.subplot(111).spines['bottom'].set_position('zero') 40 | plt.title('$Kulish$') 41 | plt.ylabel('$y=sin(x)$') 42 | plt.grid(True) 43 | plt.show() 44 | 45 | -------------------------------------------------------------------------------- /Numerical algorithms/Solving system/gauss.py: -------------------------------------------------------------------------------- 1 | # To obtain the inverse matrix: 2 | def inv(matrix): 3 | 4 | matrix_size = len(matrix) 5 | 6 | result = [[0 for i in range(0, matrix_size)] for j in range(0, matrix_size)] 7 | 8 | for i in range(0, matrix_size): 9 | column = for_column(matrix, i) 10 | for j in range(0, matrix_size): 11 | result[j][i] = column[j] 12 | 13 | return result 14 | 15 | # To convert a matrix into an inverse matrix: 16 | def for_column(our_matrix, column): 17 | 18 | matrix_size = len(our_matrix) 19 | mega_matrix = [[our_matrix[i][j] for j in range(matrix_size)] for i in range(matrix_size)] 20 | new_column = [0 for i in range(matrix_size)] 21 | 22 | for i in range(matrix_size): 23 | mega_matrix[i].append(float(i == column)) 24 | 25 | for i in range(0, matrix_size): 26 | if mega_matrix[i][i] == 0: 27 | for j in range(i + 1, matrix_size): 28 | if mega_matrix[j][j] != 0: 29 | mega_matrix[i], mega_matrix[j] = mega_matrix[j], mega_matrix[i] 30 | for j in range(i + 1, matrix_size): 31 | d = - mega_matrix[j][i] / mega_matrix[i][i] 32 | for k in range(0, matrix_size + 1): 33 | mega_matrix[j][k] += d * mega_matrix[i][k] 34 | 35 | for i in range(matrix_size - 1, -1, -1): 36 | for_result = 0 37 | for j in range(matrix_size): 38 | for_result += mega_matrix[i][j] * new_column[j] 39 | new_column[i] = (mega_matrix[i][matrix_size] - for_result) / mega_matrix[i][i] 40 | 41 | return new_column 42 | 43 | # Multiplication of SLAU to column: 44 | def multi(SLAU, column): 45 | 46 | column_size = len(column) 47 | result = [0 for j in range(column_size)] 48 | 49 | for j in range(column_size): 50 | for k in range(column_size): 51 | result[j] += column[k] * SLAU[j][k] 52 | 53 | return result 54 | -------------------------------------------------------------------------------- /Numerical algorithms/Solving system/gauss_seidel.py: -------------------------------------------------------------------------------- 1 | from math import sqrt 2 | 3 | 4 | def gauss_seidel(A, b, eps): 5 | n = len(A) # размерность матрицы 6 | x = [1 for i in range(n)] # инициализация вектора(приближение) 7 | 8 | converge = False # сходимость 9 | while not converge: 10 | x_new = x.copy() # предыдущее приближение 11 | for i in range(n): 12 | s1 = sum(A[i][j] * x_new[j] for j in range(i)) 13 | s2 = sum(A[i][j] * x[j] for j in range(i + 1, n)) 14 | x_new[i] = (b[i] - s1 - s2) / A[i][i] 15 | 16 | converge = sqrt(sum((x_new[i] - x[i]) ** 2 for i in range(n))) <= eps 17 | x = x_new 18 | return x 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Algorithms

2 |

Here is a custom implementation of many algorithms. Edits and improvements are welcomed. Below is a list for a quick transition.

3 | 4 |

Sorting algorithms

5 | 47 | 48 |

Numerical algorithms

49 | 89 | 90 |

Cryptography

91 |

(presented in this repository) 92 |

121 | 122 |

Computer graphics

123 | 162 | 163 |

Number theoretic algorithms

164 | 228 | 229 | 230 |
231 | 232 | 233 |

Structures

234 | 235 |

Primitive types

236 | 246 |

247 |
248 |

Materials used

249 | 252 |
253 | 254 |
COMMENT:

This list can use links to other my projects where these algorithms were used. There may be errors and shortcomings. These algorithms will be divided into separate modules and improved in the last turn due to lack of time.

255 | 256 | #### Legend: 257 | 264 | -------------------------------------------------------------------------------- /Sorting algorithms/README.md: -------------------------------------------------------------------------------- 1 | # Sorting algorithms 2 | In computer science a sorting algorithm is an algorithm that puts elements of a list in a certain order. The most-used 3 | orders are numerical order and lexicographical order. Efficient sorting is important for optimizing the use of other 4 | algorithms (such as search and merge algorithms) which require input data to be in sorted lists; it is also often useful 5 | for canonicalizing data and for producing human-readable output. [Wiki] 6 | 7 | ## Exchange sorts 8 | ### Bubble Sort 9 | ![Imgur](http://i.imgur.com/sAvHPFT.gif) 10 | #### Idea 11 | Simple sorting algorithm that repeatedly steps through the list to be sorted, compares each pair of adjacent items and swaps them if they are in the wrong order. The pass through the list is repeated until no swaps are needed, which indicates that the list is sorted. The algorithm, which is a comparison sort, is named for the way smaller or larger elements "bubble" to the top of the list. Although the algorithm is simple, it is too slow and impractical for most problems even when compared to insertion sort. It can be practical if the input is usually in sorted order but may occasionally have some out-of-order elements nearly in position. 12 | #### Advantages 13 | * Simple 14 | * Can detect that the list is sorted efficiently 15 | #### Disadvantages 16 | * Slow 17 | #### Possible Improvements 18 | * The n-th pass finds the n-th largest element and puts it into its final place. So, the inner loop can avoid looking at the last n − 1 items when running for the n-th time. 19 | * More than one element is placed in their final position on a single pass. In particular, after every pass, all elements after the last swap are sorted, and do not need to be checked again. 20 | #### Complexity 21 | O(n^2) 22 | #### Stability 23 | * Stable 24 | ## Selection sorts 25 | ## Insertion sorts 26 | ## Merge sorts 27 | 28 | ## Literature and links 29 | * Knuth, Donald E., Sorting and Searching, The Art of Computer Programming, 3 30 | * RosettaCode::Sorting Algorithms 31 | * AlgoList 32 | -------------------------------------------------------------------------------- /Sorting algorithms/bubble sort.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | 4 | N = 1000 5 | 6 | 7 | def std_bubble_sort(x): 8 | for i in range(len(x)): 9 | for j in range(i+1, len(x)): 10 | if x[i] > x[j]: 11 | x[j], x[i] = x[i], x[j] 12 | return x 13 | 14 | 15 | def opt_bubble_sort(x): 16 | n = len(x) 17 | while n != 0: 18 | newn = 0 19 | for i in range(1, n): 20 | if x[i-1] > x[i]: 21 | x[i-1], x[i] = x[i], x[i-1] 22 | newn = i 23 | 24 | n = newn 25 | return x 26 | 27 | 28 | if __name__ == "__main__": 29 | a = [] 30 | b = [] 31 | c = [] 32 | for i in range(N): 33 | a.append(i) 34 | b.append(N-i) 35 | c.append(random.randint(-N, N)) 36 | 37 | print("NO OPTIMIZED std_bubble_sort(x)") 38 | 39 | print("\n...SORTING ARRAY...") 40 | st = time.time() 41 | na = std_bubble_sort(a) 42 | end = time.time() 43 | print(na, "\nTIME:", (end - st), " sec") 44 | 45 | print("\n...REVERSE ARRAY...") 46 | st = time.time() 47 | nb = std_bubble_sort(b) 48 | end = time.time() 49 | print(nb, "\nTIME:", (end - st), " sec") 50 | 51 | print("\n...RANDOM ARRAY...") 52 | st = time.time() 53 | nc = std_bubble_sort(c) 54 | end = time.time() 55 | print(nc, "\nTIME:", (end - st), " sec") 56 | 57 | print("\n\nOPTIMIZED opt_bubble_sort(x)") 58 | 59 | print("\n...SORTING ARRAY...") 60 | st = time.time() 61 | na = opt_bubble_sort(a) 62 | end = time.time() 63 | print(na, "\nTIME:", (end - st), " sec") 64 | 65 | print("\n...REVERSE ARRAY...") 66 | st = time.time() 67 | nb = opt_bubble_sort(b) 68 | end = time.time() 69 | print(nb, "\nTIME:", (end - st), " sec") 70 | 71 | print("\n...RANDOM ARRAY...") 72 | st = time.time() 73 | nc = opt_bubble_sort(c) 74 | end = time.time() 75 | print(nc, "\nTIME:", (end - st), " sec") 76 | -------------------------------------------------------------------------------- /Sorting algorithms/cocktail sort.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | 4 | N = 10000 5 | 6 | 7 | def std_cocktail_sort (x): 8 | left = 0 9 | right = len(x)-1 10 | 11 | while left <= right: 12 | for i in range(left, right): 13 | if x[i] > x[i+1]: 14 | x[i], x[i+1] = x[i+1], x[i] 15 | right = right - 1 16 | 17 | for i in range(right, left, -1): 18 | if x[i-1] > x[i]: 19 | x[i-1], x[i] = x[i], x[i-1] 20 | left = left + 1 21 | 22 | return x 23 | 24 | 25 | def opt_cocktail_sort(x): 26 | for i in range(len(x)//2): 27 | swap = False 28 | for j in range(1+i, len(x)-i): 29 | if x[j] < x[j-1]: 30 | x[j], x[j - 1] = x[j - 1], x[j] 31 | swap = True 32 | if not swap: 33 | break 34 | swap = False 35 | for j in range(len(x)-i-1, i, -1): 36 | if x[j] < x[j-1]: 37 | x[j], x[j - 1] = x[j - 1], x[j] 38 | swap = True 39 | if not swap: 40 | break 41 | 42 | return x 43 | 44 | 45 | if __name__ == "__main__": 46 | a = [] 47 | b = [] 48 | c = [] 49 | for i in range(N): 50 | a.append(i) 51 | b.append(N-i) 52 | c.append(random.randint(-N, N)) 53 | 54 | print("NO OPTIMIZED std_cocktail_sort(x)") 55 | 56 | print("\n...SORTING ARRAY...") 57 | st = time.time() 58 | na = std_cocktail_sort(a) 59 | end = time.time() 60 | print("\nTIME:", (end - st), " sec") 61 | 62 | print("\n...REVERSE ARRAY...") 63 | st = time.time() 64 | nb = std_cocktail_sort(b) 65 | end = time.time() 66 | print( "\nTIME:", (end - st), " sec") 67 | 68 | print("\n...RANDOM ARRAY...") 69 | st = time.time() 70 | nc = std_cocktail_sort(c) 71 | end = time.time() 72 | print("\nTIME:", (end - st), " sec") 73 | 74 | print("\n\nOPTIMIZED opt_cocktail_sort(x)") 75 | 76 | print("\n...SORTING ARRAY...") 77 | st = time.time() 78 | na = opt_cocktail_sort(a) 79 | end = time.time() 80 | print("\nTIME:", (end - st), " sec") 81 | 82 | print("\n...REVERSE ARRAY...") 83 | st = time.time() 84 | nb = opt_cocktail_sort(b) 85 | end = time.time() 86 | print("\nTIME:", (end - st), " sec") 87 | 88 | print("\n...RANDOM ARRAY...") 89 | st = time.time() 90 | nc = opt_cocktail_sort(c) 91 | end = time.time() 92 | print("\nTIME:", (end - st), " sec") 93 | 94 | 95 | -------------------------------------------------------------------------------- /Sorting algorithms/comb sort.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | 4 | N = 100000 5 | 6 | 7 | def std_comb_sort(x): 8 | gap = len(x) 9 | swaps = True 10 | while gap > 1 or swaps: 11 | gap = max(1, int(gap / 1.25)) # minimum gap is 1 12 | swaps = False 13 | for i in range(len(x) - gap): 14 | j = i+gap 15 | if x[i] > x[j]: 16 | x[i], x[j] = x[j], x[i] 17 | swaps = True 18 | 19 | return x 20 | 21 | 22 | def opt_comb_sort(x): 23 | l = len(x) 24 | gap = (l * 10 // 13) if l > 1 else 0 25 | while gap: 26 | if 8 < gap < 11: ## variant "comb-11" 27 | gap = 11 28 | swapped = False 29 | for i in range(l - gap): 30 | if x[i + gap] < x[i]: 31 | x[i], x[i + gap] = x[i + gap], x[i] 32 | swapped = True 33 | gap = (gap * 10 // 13) or swapped 34 | 35 | return x 36 | 37 | 38 | 39 | if __name__ == "__main__": 40 | a = [] 41 | b = [] 42 | c = [] 43 | for i in range(N): 44 | a.append(i) 45 | b.append(N-i) 46 | c.append(random.randint(-N, N)) 47 | 48 | print("NO OPTIMIZED std_comb_sort(x)") 49 | 50 | print("\n...SORTING ARRAY...") 51 | st = time.time() 52 | na = std_comb_sort(a) 53 | end = time.time() 54 | print("\nTIME:", (end - st), " sec") 55 | 56 | print("\n...REVERSE ARRAY...") 57 | st = time.time() 58 | nb = std_comb_sort(b) 59 | end = time.time() 60 | print("\nTIME:", (end - st), " sec") 61 | 62 | print("\n...RANDOM ARRAY...") 63 | st = time.time() 64 | nc = std_comb_sort(c) 65 | end = time.time() 66 | print("\nTIME:", (end - st), " sec") 67 | 68 | print("\n\nOPTIMIZED opt_comb_sort(x)") 69 | 70 | print("\n...SORTING ARRAY...") 71 | st = time.time() 72 | na = opt_comb_sort(a) 73 | end = time.time() 74 | print("\nTIME:", (end - st), " sec") 75 | 76 | print("\n...REVERSE ARRAY...") 77 | st = time.time() 78 | nb = opt_comb_sort(b) 79 | end = time.time() 80 | print("\nTIME:", (end - st), " sec") 81 | 82 | print("\n...RANDOM ARRAY...") 83 | st = time.time() 84 | nc = opt_comb_sort(c) 85 | end = time.time() 86 | print("\nTIME:", (end - st), " sec") 87 | -------------------------------------------------------------------------------- /Sorting algorithms/counting sort.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | from collections import defaultdict 4 | 5 | N = 1000 6 | 7 | 8 | def std_counting_sort(x, mn=0, mx=N): 9 | n = len(x) 10 | m = mx + 1 11 | count = [0] * m 12 | for a in x: 13 | count[a] += 1 14 | i = 0 15 | for a in range(m): 16 | for c in range(count[a]): 17 | x[i] = a 18 | i += 1 19 | return x 20 | 21 | 22 | def opt_counting_sort(x, mn=0, mx=N): 23 | count = defaultdict(int) 24 | for i in x: 25 | count[i] += 1 26 | result = [] 27 | for j in range(mn, mx + 1): 28 | result += [j] * count[j] 29 | return result 30 | 31 | 32 | if __name__ == "__main__": 33 | a = [] 34 | b = [] 35 | c = [] 36 | for i in range(N): 37 | a.append(i) 38 | b.append(N - i) 39 | c.append(random.randint(-N, N)) 40 | 41 | print("NO OPTIMIZED std_shell_sort(x)") 42 | 43 | print("\n...SORTING ARRAY...") 44 | st = time.time() 45 | na = std_counting_sort(a) 46 | end = time.time() 47 | print(na == sorted(a)) 48 | print("\nTIME:", (end - st), " sec") 49 | 50 | print("\n...REVERSE ARRAY...") 51 | st = time.time() 52 | nb = std_counting_sort(b) 53 | end = time.time() 54 | print(nb == sorted(b)) 55 | print("\nTIME:", (end - st), " sec") 56 | 57 | print("\n...RANDOM ARRAY...") 58 | st = time.time() 59 | nc = std_counting_sort(c, mn=-N, mx=N) 60 | end = time.time() 61 | print(nc == sorted(c)) 62 | print("\nTIME:", (end - st), " sec") 63 | 64 | print("\n\nOPTIMIZED opt_shell_sort(x)") 65 | 66 | print("\n...SORTING ARRAY...") 67 | st = time.time() 68 | na = opt_counting_sort(a) 69 | end = time.time() 70 | print(na == sorted(a)) 71 | print("\nTIME:", (end - st), " sec") 72 | 73 | print("\n...REVERSE ARRAY...") 74 | st = time.time() 75 | nb = opt_counting_sort(b) 76 | end = time.time() 77 | print(nb == sorted(b)) 78 | print("\nTIME:", (end - st), " sec") 79 | 80 | print("\n...RANDOM ARRAY...") 81 | st = time.time() 82 | nc = opt_counting_sort(c, mn=-N, mx=N) 83 | end = time.time() 84 | print(nc == sorted(c)) 85 | print("\nTIME:", (end - st), " sec") 86 | -------------------------------------------------------------------------------- /Sorting algorithms/gnome sort.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | 4 | N = 1000 5 | 6 | 7 | def std_gnome_sort(x): 8 | i = 1 9 | while i < len(x): 10 | if not i or x[i - 1] <= x[i]: 11 | i += 1 12 | else: 13 | x[i], x[i - 1] = x[i - 1], x[i] 14 | i -= 1 15 | return x 16 | 17 | 18 | def opt_gnome_sort(x): 19 | i, j, size = 1, 2, len(x) 20 | while i < size: 21 | if x[i - 1] <= x[i]: 22 | i, j = j, j + 1 23 | else: 24 | x[i - 1], x[i] = x[i], x[i - 1] 25 | i -= 1 26 | if i == 0: 27 | i, j = j, j + 1 28 | 29 | return x 30 | 31 | 32 | if __name__ == "__main__": 33 | a = [] 34 | b = [] 35 | c = [] 36 | for i in range(N): 37 | a.append(i) 38 | b.append(N - i) 39 | c.append(random.randint(-N, N)) 40 | 41 | print("NO OPTIMIZED std_shell_sort(x)") 42 | 43 | print("\n...SORTING ARRAY...") 44 | st = time.time() 45 | na = std_gnome_sort(a) 46 | end = time.time() 47 | print(na == sorted(a)) 48 | print("\nTIME:", (end - st), " sec") 49 | 50 | print("\n...REVERSE ARRAY...") 51 | st = time.time() 52 | nb = std_gnome_sort(b) 53 | end = time.time() 54 | print(nb == sorted(b)) 55 | print("\nTIME:", (end - st), " sec") 56 | 57 | print("\n...RANDOM ARRAY...") 58 | st = time.time() 59 | nc = std_gnome_sort(c) 60 | end = time.time() 61 | print(nc == sorted(c)) 62 | print("\nTIME:", (end - st), " sec") 63 | 64 | print("\n\nOPTIMIZED opt_shell_sort(x)") 65 | 66 | print("\n...SORTING ARRAY...") 67 | st = time.time() 68 | na = opt_gnome_sort(a) 69 | end = time.time() 70 | print(na == sorted(a)) 71 | print("\nTIME:", (end - st), " sec") 72 | 73 | print("\n...REVERSE ARRAY...") 74 | st = time.time() 75 | nb = opt_gnome_sort(b) 76 | end = time.time() 77 | print(nb == sorted(b)) 78 | print("\nTIME:", (end - st), " sec") 79 | 80 | print("\n...RANDOM ARRAY...") 81 | st = time.time() 82 | nc = opt_gnome_sort(c) 83 | end = time.time() 84 | print(nc == sorted(c)) 85 | print("\nTIME:", (end - st), " sec") 86 | -------------------------------------------------------------------------------- /Sorting algorithms/insertion sort.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | 4 | N = 1000 5 | 6 | 7 | def std_insection_sort (x): 8 | for i in range(1, len(x)): 9 | key = x[i] 10 | j = i-1 11 | while (j >= 0) and (x[j] > key): 12 | x[j+1] = x[j] 13 | j = j-1 14 | x[j+1] = key 15 | 16 | return x 17 | 18 | 19 | def opt_insection_sort(x): 20 | for i in range(1, len(x)): 21 | key = x[i] 22 | left = 0 23 | right = i 24 | while right > left: 25 | mid = int(left+right) // 2 26 | if x[mid] < key: 27 | left = mid+1 28 | else: 29 | right = mid-1 30 | 31 | for j in range(i-1, left-1, -1): 32 | x[j+1] = x[j] 33 | x[left] = key 34 | 35 | return x 36 | 37 | 38 | if __name__ == "__main__": 39 | a = [] 40 | b = [] 41 | c = [] 42 | for i in range(N): 43 | a.append(i) 44 | b.append(N-i) 45 | c.append(random.randint(-N, N)) 46 | 47 | print("NO OPTIMIZED std_insection_sort(x)") 48 | 49 | print("\n...SORTING ARRAY...") 50 | st = time.time() 51 | na = std_insection_sort(a) 52 | end = time.time() 53 | print("\nTIME:", (end - st), " sec") 54 | 55 | print("\n...REVERSE ARRAY...") 56 | st = time.time() 57 | nb = std_insection_sort(b) 58 | end = time.time() 59 | print("\nTIME:", (end - st), " sec") 60 | 61 | print("\n...RANDOM ARRAY...") 62 | st = time.time() 63 | nc = std_insection_sort(c) 64 | end = time.time() 65 | print("\nTIME:", (end - st), " sec") 66 | 67 | print("\n\nOPTIMIZED opt_insection_sort(x)") 68 | 69 | print("\n...SORTING ARRAY...") 70 | st = time.time() 71 | na = opt_insection_sort(a) 72 | end = time.time() 73 | print("\nTIME:", (end - st), " sec") 74 | 75 | print("\n...REVERSE ARRAY...") 76 | st = time.time() 77 | nb = opt_insection_sort(b) 78 | end = time.time() 79 | print("\nTIME:", (end - st), " sec") 80 | 81 | print("\n...RANDOM ARRAY...") 82 | st = time.time() 83 | nc = opt_insection_sort(c) 84 | end = time.time() 85 | print("\nTIME:", (end - st), " sec") 86 | -------------------------------------------------------------------------------- /Sorting algorithms/iterative qsort.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | 4 | def partition(arr,l,h): 5 | i = ( l - 1 ) 6 | x = arr[h] 7 | 8 | for j in range(l , h): 9 | if arr[j] <= x: 10 | 11 | # increment index of smaller element 12 | i = i+1 13 | arr[i],arr[j] = arr[j],arr[i] 14 | 15 | arr[i+1],arr[h] = arr[h],arr[i+1] 16 | return (i+1) 17 | 18 | # Function to do Quick sort 19 | # arr[] --> Array to be sorted, 20 | # l --> Starting index, 21 | # h --> Ending index 22 | def quickSortIterative(arr,l,h): 23 | 24 | # Create an auxiliary stack 25 | size = h - l + 1 26 | stack = [0] * (size) 27 | 28 | # initialize top of stack 29 | top = -1 30 | 31 | # push initial values of l and h to stack 32 | top = top + 1 33 | stack[top] = l 34 | top = top + 1 35 | stack[top] = h 36 | 37 | # Keep popping from stack while is not empty 38 | while top >= 0: 39 | 40 | # Pop h and l 41 | h = stack[top] 42 | top = top - 1 43 | l = stack[top] 44 | top = top - 1 45 | 46 | # Set pivot element at its correct position in 47 | # sorted array 48 | p = partition( arr, l, h ) 49 | 50 | # If there are elements on left side of pivot, 51 | # then push left side to stack 52 | if p-1 > l: 53 | top = top + 1 54 | stack[top] = l 55 | top = top + 1 56 | stack[top] = p - 1 57 | 58 | # If there are elements on right side of pivot, 59 | # then push right side to stack 60 | if p+1 < h: 61 | top = top + 1 62 | stack[top] = p + 1 63 | top = top + 1 64 | stack[top] = h 65 | 66 | # Driver code to test above 67 | arr = [2]*10000000 68 | n = len(arr) 69 | quickSortIterative(arr, 0, n-1) 70 | 71 | 72 | # This code is contributed by Mohit Kumra 73 | -------------------------------------------------------------------------------- /Sorting algorithms/quick sort.py: -------------------------------------------------------------------------------- 1 | import random 2 | def sort (x): 3 | if len(x) <= 1: 4 | return(x) 5 | else: 6 | q = x[len(x) // 2] 7 | l = [] 8 | m = [] 9 | r = [] 10 | for i in range(len(x)): 11 | if x[i] < q: 12 | l.append(x[i]) 13 | elif x[i] == q: 14 | m.append(x[i]) 15 | else: 16 | r.append(x[i]) 17 | 18 | return(sort(l) + m + sort(r)) 19 | 20 | 21 | a = [] 22 | b = [] 23 | c = [] 24 | for i in range(100): 25 | a.append(i) 26 | b.append(100-i) 27 | c.append(random.randint(-100, 100)) 28 | 29 | a = sort(a) 30 | b = sort(b) 31 | c = sort(c) 32 | 33 | print(a) 34 | print(b) 35 | print(c) 36 | -------------------------------------------------------------------------------- /Sorting algorithms/selection sort.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | 4 | N = 10000 5 | 6 | 7 | def std_selection_sort(x): 8 | for i in range(len(x)): 9 | min_ind = i 10 | for j in range(i, len(x)): 11 | if x[min_ind] > x[j]: 12 | min_ind = j 13 | x[i], x[min_ind] = x[min_ind], x[i] 14 | 15 | return x 16 | 17 | 18 | def opt_selection_sort(x): 19 | for i, e in enumerate(x): 20 | mn = min(range(i, len(x)), key=x.__getitem__) 21 | x[i], x[mn] = x[mn], e 22 | return x 23 | 24 | 25 | if __name__ == "__main__": 26 | a = [] 27 | b = [] 28 | c = [] 29 | for i in range(N): 30 | a.append(i) 31 | b.append(N - i) 32 | c.append(random.randint(-N, N)) 33 | 34 | print("NO OPTIMIZED std_shell_sort(x)") 35 | 36 | print("\n...SORTING ARRAY...") 37 | st = time.time() 38 | na = std_selection_sort(a) 39 | end = time.time() 40 | print("\nTIME:", (end - st), " sec") 41 | 42 | print("\n...REVERSE ARRAY...") 43 | st = time.time() 44 | nb = std_selection_sort(b) 45 | end = time.time() 46 | print("\nTIME:", (end - st), " sec") 47 | 48 | print("\n...RANDOM ARRAY...") 49 | st = time.time() 50 | nc = std_selection_sort(c) 51 | end = time.time() 52 | print("\nTIME:", (end - st), " sec") 53 | 54 | print("\n\nOPTIMIZED opt_shell_sort(x)") 55 | 56 | print("\n...SORTING ARRAY...") 57 | st = time.time() 58 | na = opt_selection_sort(a) 59 | end = time.time() 60 | print("\nTIME:", (end - st), " sec") 61 | 62 | print("\n...REVERSE ARRAY...") 63 | st = time.time() 64 | nb = opt_selection_sort(b) 65 | end = time.time() 66 | print("\nTIME:", (end - st), " sec") 67 | 68 | print("\n...RANDOM ARRAY...") 69 | st = time.time() 70 | nc = opt_selection_sort(c) 71 | end = time.time() 72 | print("\nTIME:", (end - st), " sec") 73 | -------------------------------------------------------------------------------- /Sorting algorithms/shell sort.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | 4 | N = 10000 5 | 6 | def std_shell_sort(x): 7 | gap_prev = 1 8 | gap = 1 9 | sorte = True 10 | while True: 11 | if gap == len(x): 12 | break 13 | elif gap > len(x): 14 | gap = gap_prev 15 | break 16 | gap_prev = gap 17 | gap = gap_prev * 3 + 1 18 | 19 | while gap >= 1: 20 | i = gap 21 | while i <= len(x) - 1: 22 | if x[i] < x[i - gap]: 23 | x[i], x[i - gap] = x[i - gap], x[i] 24 | sorte = True 25 | i = i + 1 26 | if sorte == False: 27 | gap = (gap - 1) // 3 28 | sorte = False 29 | return x 30 | 31 | 32 | def opt_shell_sort(x): 33 | inc = len(x) // 2 34 | while inc: 35 | for i, el in enumerate(x): 36 | while i >= inc and x[i - inc] > el: 37 | x[i] = x[i - inc] 38 | i -= inc 39 | x[i] = el 40 | inc = 1 if inc == 2 else int(inc * 5.0 / 11) 41 | return x 42 | 43 | 44 | if __name__ == "__main__": 45 | a = [] 46 | b = [] 47 | c = [] 48 | for i in range(N): 49 | a.append(i) 50 | b.append(N - i) 51 | c.append(random.randint(-N, N)) 52 | 53 | print("NO OPTIMIZED std_shell_sort(x)") 54 | 55 | print("\n...SORTING ARRAY...") 56 | st = time.time() 57 | na = std_shell_sort(a) 58 | end = time.time() 59 | print("\nTIME:", (end - st), " sec") 60 | 61 | print("\n...REVERSE ARRAY...") 62 | st = time.time() 63 | nb = std_shell_sort(b) 64 | end = time.time() 65 | print("\nTIME:", (end - st), " sec") 66 | 67 | print("\n...RANDOM ARRAY...") 68 | st = time.time() 69 | nc = std_shell_sort(c) 70 | end = time.time() 71 | print("\nTIME:", (end - st), " sec") 72 | 73 | print("\n\nOPTIMIZED opt_shell_sort(x)") 74 | 75 | print("\n...SORTING ARRAY...") 76 | st = time.time() 77 | na = opt_shell_sort(a) 78 | end = time.time() 79 | print("\nTIME:", (end - st), " sec") 80 | 81 | print("\n...REVERSE ARRAY...") 82 | st = time.time() 83 | nb = opt_shell_sort(b) 84 | end = time.time() 85 | print("\nTIME:", (end - st), " sec") 86 | 87 | print("\n...RANDOM ARRAY...") 88 | st = time.time() 89 | nc = opt_shell_sort(c) 90 | end = time.time() 91 | print("\nTIME:", (end - st), " sec") 92 | --------------------------------------------------------------------------------