diff --git "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" index 07560cfa..757015f3 100644 --- "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" +++ "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" @@ -9,3 +9,45 @@ Подсказка: обратите внимание, сортируем не по возрастанию, как в примере, а по убыванию """ +from random import randint +from timeit import timeit + + +def create_list(list_len, l_border, r_border): + return [randint(l_border, r_border - 1) for _ in range(list_len)] + + +# оригинальный +def bubble_sort(base_list): + flag = False + for idx in range(len(base_list[:]) - 1, 0, -1): + if base_list[idx] > base_list[idx-1]: + base_list[idx], base_list[idx-1], flag = base_list[idx-1], base_list[idx], True + return bubble_sort(base_list) if flag else base_list[:] + + +#оптимизированный +def bubble_sort_opt(base_list, itr=0): + flag = False + for idx in range(len(base_list[:]) - 1, itr, -1): + if base_list[idx] > base_list[idx-1]: + base_list[idx], base_list[idx-1], flag = base_list[idx-1], base_list[idx], True + return bubble_sort_opt(base_list, itr+1) if flag else base_list[:] + + +a = create_list(10, 0, 10) +print(a) +print(bubble_sort(a)) +print(bubble_sort_opt(a)) +print('Пузырьковая: ', timeit('bubble_sort(create_list(1000, 0, 10))', 'from __main__ import bubble_sort, create_list', number=100)) +print('Оптимизиров: ', timeit('bubble_sort_opt(create_list(1000, 0, 10))', 'from __main__ import bubble_sort_opt, create_list', number=100)) + +""" +[4, 9, 6, 2, 2, 3, 5, 3, 3, 3] +[9, 6, 5, 4, 3, 3, 3, 3, 2, 2] +[9, 6, 5, 4, 3, 3, 3, 3, 2, 2] +Пузырьковая: 8.634379411007103 +Оптимизиров: 6.528080139003578 +# Вывод: легкая оптимизация алгоритма высвободило почти 20% ресурсов. +""" + diff --git "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" index 73d3dfb6..50206036 100644 --- "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" +++ "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" @@ -8,3 +8,91 @@ Исходный - [46.11436617832828, 41.62921998361278, 18.45859540989644, 12.128870723745806, 8.025098788570562] Отсортированный - [8.025098788570562, 12.128870723745806, 18.45859540989644, 41.62921998361278, 46.11436617832828] """ +# 2. Отсортируйте по возрастанию методом слияния одномерный вещественный массив, +# заданный случайными числами на промежутке [0; 50). +# Выведите на экран исходный и отсортированный массивы. +from random import random +from random import randint +from timeit import timeit + +# import sys +# sys.setrecursionlimit(100000) + + +def create_list_int(list_len, l_border, r_border): + return [randint(l_border, r_border - 1) for _ in range(list_len)] + + +def create_list_float(list_len, l_border, r_border): + return [randint(l_border, r_border - 1) + random() for _ in range(list_len)] + +# Читабельный вариант +def merge_sort2(list1, list2): + tmp = [] + while len(list1) > 0: + while len(list2) > 0 and list2[0] <= list1[0]: + tmp.append(list2.pop(0)) + tmp.append(list1.pop(0)) + return tmp + list2 + + +def merge_sort(base_list): + if len(base_list) > 2: + half = len(base_list) // 2 + return merge_sort2(merge_sort(base_list[:half]), merge_sort(base_list[half:])) + else: + if len(base_list) == 1: + return base_list + else: + return base_list if base_list[0] < base_list[1] else base_list[::-1] + +# НЕЕЕЕЕЕЕЕчитабельный вариант! +def merge_sort_opt2(list1, list2, tmp=[]): + while len(list1) > 0: + while len(list2) > 0 and list2[0] <= list1[0]: + tmp.append(list2.pop(0)) + tmp.append(list1.pop(0)) + return tmp + list2 + +def merge_sort_opt(base_list): + return merge_sort_opt2(merge_sort(base_list[:len(base_list) // 2]), merge_sort(base_list[len(base_list) // 2:])) \ + if len(base_list) > 2 else base_list if len(base_list) == 1 else base_list \ + if base_list[0] < base_list[1] else base_list[::-1] + + +a = create_list_float(8, 0, 50) +print(a) +print(merge_sort(a)) +print(merge_sort_opt(a)) +print('Обычный: ', timeit('merge_sort(create_list_float(10000, 0, 10))', 'from __main__ import merge_sort, merge_sort2, create_list_float', number=100)) +print('Оптимизиров: ', timeit('merge_sort_opt(create_list_float(10000, 0, 10))', 'from __main__ import merge_sort_opt, merge_sort_opt2, create_list_float', number=100)) +""" +[24.060749050634755, 5.569825488205687, 12.099656999933002, 25.489810820912094, 26.71010855578925, 20.318494463628316, 1.8343820847442003, 33.16803571517379] +[1.8343820847442003, 5.569825488205687, 12.099656999933002, 20.318494463628316, 24.060749050634755, 25.489810820912094, 26.71010855578925, 33.16803571517379] +[1.8343820847442003, 5.569825488205687, 12.099656999933002, 20.318494463628316, 24.060749050634755, 25.489810820912094, 26.71010855578925, 33.16803571517379] +Обычный: 0.30818897799326805 +Оптимизиров: 0.35243779300071765 + +#Вывод: вроде бы более лаконичная запись, а привела к перерасходу ресурсов. Вот как бывает при "неправильной" оптимизации +# причем на более длинных массивах разница увеличивается +# Если длинна массива = 1000 +# Обычный: 4.47612431399466 +# Оптимизиров: 5.975955189001979 +""" + + + + + + +""" +b = [1, 3, 8] +c = [1, 2, 7, 9] +print(b) +print(c) +print(merge_sort2(b, c)) +b = [1, 3, 8] +c = [1, 2, 7, 9] +print(merge_sort_opt2(b, c)) +print('-----------------------------------------') +""" \ No newline at end of file diff --git "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" index 33530404..20e889e2 100644 --- "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" +++ "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" @@ -6,3 +6,79 @@ массива. Но если это слишком сложно, то используйте метод сортировки, который не рассматривался на уроках """ +from random import random +from random import randint +from timeit import timeit + + +def create_list_int(list_len, l_border, r_border): + return [randint(l_border, r_border - 1) for _ in range(list_len * 2 + 1)] + + +# Использую set, что дает прирост производительности +def get_median(base_list): + for val in base_list: + cnt1 = cnt2 = 0 + cnt3 = base_list.count(val) + for val2 in base_list: + if val == val2: + continue + if val2 < val: + cnt1 += 1 + else: + cnt2 += 1 + if abs(cnt1-cnt2) <= cnt3: + return val + return None + + +# Использую set, что дает прирост производительности +def get_median_opt(base_list): + for val in set(base_list): + cnt1 = cnt2 = 0 + cnt3 = base_list.count(val) + for val2 in base_list: + if val == val2: + continue + if val2 < val: + cnt1 += 1 + else: + cnt2 += 1 + if abs(cnt1-cnt2) <= cnt3: + return val + return None + + +a = create_list_int(5, 0, 10) +print(a) +print(sorted(a)) +print(get_median(a)) +print(get_median_opt(a)) +""" +[5, 2, 0, 5, 9, 3, 3, 7, 3, 0, 2] +[0, 0, 2, 2, 3, 3, 3, 5, 5, 7, 9] +3 +3 +""" +print('Обычный: ', + timeit('get_median(create_list_int(500,0,1000000))', 'from __main__ import get_median, create_list_int', + number=100)) +print('Оптимиз: ', + timeit('get_median_opt(create_list_int(500,0,1000000))', 'from __main__ import get_median_opt, create_list_int', + number=100)) +""" +Обычный: 5.44049578999693 +Оптимиз: 6.0076921620056964 + +""" +# Сделаем разброс возможных значений массива минимальными +print('Обычный: ', + timeit('get_median(create_list_int(500,0,10))', 'from __main__ import get_median, create_list_int', number=100)) +print('Оптимиз: ', + timeit('get_median_opt(create_list_int(500,0,10))', 'from __main__ import get_median_opt, create_list_int', + number=100)) +""" +Обычный: 0.19541699200635776 +Оптимиз: 0.15574709400243592 +""" +# ВЫВОД: в зависимости от типа входных данных разные алгоритмы могут как ускорить, так и замедлить работу