Skip to content
Open

Dz07 #567

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions Урок 7. Практическое задание/task_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

на момент выполнения строки 41 массив будет уже отсортирован
добавьте перед 41 принт(a)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да, действительно косяк, но алгоритм работает
Строки 40 и 41 надо заменить на:
print(bubble_sort(a[:]))
print(bubble_sort_opt(a[:]))

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Спасибо

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))

"""

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а вот здесь уже хорошо
Сергей, напишите в чем суть ваше оптимизации и для чего применена рекурсия?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Оптимизация не Бог весть какая, просто вместо полного сканирования входного массива, на N-ой итерации проверяются только [N:0:-1] элементы массива.
Рекурсия как-то сама появилась, мне кажется тут она уместна для не очень длинных массивов.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Сергей, спс за ответы

[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% ресурсов.
"""

88 changes: 88 additions & 0 deletions Урок 7. Практическое задание/task_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -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('-----------------------------------------')
"""

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

спс за замеры

76 changes: 76 additions & 0 deletions Урок 7. Практическое задание/task_3.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
"""
# ВЫВОД: в зависимости от типа входных данных разные алгоритмы могут как ускорить, так и замедлить работу
Comment thread
nubobap2015 marked this conversation as resolved.