You are on page 1of 11

Міністерство освіти і науки України

Вінницький національний технічний університет


Факультет інтелектуальних інформаційних технологій та автоматизації
Кафедра КН

Лабораторна робота №8
з дисципліни «Теорія алгоритмів»

Виконав: ст. гр. 1КН-22б. Якубишин Я. О.


Перевірив: Денисюк В. О.

Вінниця 2023
Лабораторна робота №8

Тема: програмування та аналіз алгоритму сортування лінійного рівня


складності.
Мета: проаналізувати та дослідити алгоритм сортування за лінійний час

Порядок виконання роботи

1. Тему, мету та порядок виконання роботи.


2. Ідея відповідного алгоритму сортування.
3. Власний приклад роботи відповідного алгоритму сортування на
масиві 10 чисел
4. Алгоритм сортування у графічному вигляді.
5. Теоретична оцінка складності алгоритму для трьох випадків.

5.1 для найкращого випадку.

5.2 для найгіршого випадку.

5.3 для середнього випадку.

6. Сирець алгоритму відповідного сортування.


7. Практична оцінка складності відповідного алгоритму в трьох
випадках для масивів різного розміру. Навести таблиці та відповідні
графіки часу виконання програми для трьох випадків. Кількість
значень часу має бути не менше семи.
7.1 Таблиця та графік для найкращого випадку.

7.2 Таблиця та графік для найгіршого випадку.

7.3 Таблиця та графік для середнього випадку.

8. Порівняльний аналіз теоретично та практично отриманих графіків


залежностей часів виконання програми від розмірів входу.
9. Переваги та недоліки дослідженого Вами алгоритму сортування
та Ваші міркування.
10. Розширені висновки з роботи.

1
Хід роботи

1. Ідея відповідного алгоритму сортування

Алгоритм сортування підраховуванням (counting sort) застосовують, якщо


кожний з n елементів послідовності, що відсортовується, – ціле додатне
число у відомому діапазоні (що не переважає заздалегідь відоме k). Якщо
k=О(n), то алгоритм сортування підраховуванням працює за час О(n).

Ідея цього алгоритму в тому, щоб для кожного елементу х попередньо


підрахувати, скільки елементів вхідної послідовності менше х, після чого
записати х прямо у вихідний масив відповідно до цього числа (якщо,
скажімо, 17 елементів вхідного масиву менше х, то у вихідному масиві х
повинен бути записаний на місце номер 18). Якщо в послідовності, що
відсортовується, присутні рівні числа, цю схему треба дещо модифікува-
ти, щоб не записати кілька чисел на одне місце.

Варто відзначити, що алгоритм сортування підраховуванням не по- рівнює


числа, що відсортовуються, між собою, а використовує їх як інде- кси
масиву.

2. Власний приклад роботи відповідного алгоритму сортування на масиві 8


чисел.

2
3
3. Алгоритм сортування у графічному вигляді.

Рисунок 1.3 Схема алгоритму сортування злиттям у графічному вигляді

4. Теоретична оцінка складності алгоритму для трьох випадків.

5.1 для найкращого випадку.

5.2 для найгіршого випадку.

5.3 для середнього випадку.

Оцінимо час роботи алгоритму сортування підраховуванням. Цик-


ли в рядках 1-2 і 6-7 працюють за час О(k), цикли в рядках 3-4 і 10-
11 – за час О(n), а весь алгоритм працює за час О(k+ n). Якщо
k=О(n), то час роботи є O(n).

Найкращий випадок:
O (n+k)
Найгірший випадок
O (n+k)
Середній випадок
O (n+k)

4
5. Практична оцінка складності відповідного алгоритму в трьох
випадках для масивів різного розміру. Навести таблиці та відповідні
графіки часу виконання програми для трьох випадків. Кількість значень
часу має бути не менше семи. Увага! Мінімальне та максимальне
значення часу кожним студентом підбирається індивідуально, залежно
від потужностей Вашого ПК.

n Найкращий Найгірший випадок Середній випадок


випадок
200000 0.1 0.3 0.2
400000 0.3 0.4 0.4
600000 0.5 0.7 0.6
800000 0.7 0.8 0.8
1000000 0.9 1.1 1
1200000 1.1 1.2 1.2
1500000 1.3 1.5 1.5
t, c

n, кількість елементів

Рис.1.1 графік практичної складності алгоритму методом підрахунку для


3 випадків

5
Лістинг програми для оцінки часової складності алгоритму методом
злиття для 3 випадків :
import random
import time

def countingSort(arr):
max_val =
max(arr)
count = [0] * (max_val + 1)

for num in arr:


count[num] += 1

sorted_arr = []
for i in range(len(count)):
sorted_arr.extend([i] *
count[i])

return sorted_arr

# Generate an array of numbers


size = 1000000 # Specify the size of the array
numbers = [random.randint(1, size) for _ in range(size)]

# Worst Case
worst_case_numbers = list(reversed(numbers)) # Sorted in descending order

# Best Case
best_case_numbers = sorted(numbers) # Already sorted in ascending order

# Average Case
average_case_numbers = list(numbers) # Random order

# Measure the execution time for worst case


start_time = time.time()
countingSort(worst_case_numbers)
worst_case_time = time.time() -
start_time

# Measure the execution time for best case


start_time = time.time()

countingSort(best_case_numbers) best_case_time
= time.time() - start_time
6
# Measure the execution time for average case
start_time = time.time()
countingSort(average_case_numbers)
average_case_time = time.time() - start_time

print(f"Worst Case Time: {worst_case_time:.6f} seconds")

print(f"Best Case Time: {best_case_time:.6f} seconds")

print(f"Average Case Time: {average_case_time:.6f}

Порівняльний аналіз теоретично та практично отриманих графіків


залежностей часів виконання програми від розмірів входу.
Практичні результати відповідають нашим теоретичним оцінкам, отже ми
можемо вважати, що наші теоретичні оцінки є коректними. Порівняльний
аналіз теоретичної та практичної часової складності алгоритму сортування
злиттям ми здійснили, порівнюючи графіки залежності часу виконання
програми від розміру вхідних даних.
Після практичтного аналізу ми побачили, що:
 Попередньо відсортовані вихідні послідовності з мільйона
елементів сортуються приблизно в дев’ять разів швидше, ніж
невідсортовані.
 Для попередньо відсортованих вхідних послідовностей
вимірювання відповідають очікуваній лінійній часовій складності
O(n + k).
 Для несортованих вхідних послідовностей вимірювання дещо вищі:
коли розмір масиву подвоюється, необхідний час збільшується
приблизно в 2,1-2,2 рази.
 Вхідні послідовності, відсортовані за спаданням, сортуються
мінімально повільніше, ніж попередньо відсортовані за зростанням.

6. Переваги та недоліки дослідженого Вами алгоритму сортування та


Ваші міркування.

Переваги:
1.Стійкість (зберігає порядок рівних елементів у вхідному масиві); 2.Ефективність
для обмеженого діапазону значень: Сортування підрахуванням є дуже ефективним
алгоритмом сортування, коли вхідні дані мають обмежений діапазон значень. В
такому випадку, використання масиву підрахунку, де кожному значенню
присвоюється певна позиція, дозволяє відсортувати елементи швидко з часовою
складністю O(n + k), де n - кількість елементів, а k - кількість унікальних значень.

Недоліки:
1. Додаткова пам’ять під список лічильників
2. Не працює добре для наборів даних з великим діапазоном значень.

7
8. Розширені висновки з роботи

Сортування підрахунком – це алгоритм, який підраховує кількість


елементів, що мають кожне значення, і потім використовує цю
інформацію для впорядкування елементів. Він працює шляхом створення
допоміжного масиву, в якому зберігається кількість елементів з кожним
значенням, а потім використовує цю інформацію для складання
відсортованого масиву.

Сортування підрахунком виконується неймовірно швидко. В одному з


тестів швидке сортування 100000 елементів зі значеннями від 1 до 1000
зайняло 24,44 секунди. Для сортування тих же елементів сортуванням
підрахунку треба було всього 0,88 секунд - в 27 разів менше часу.

Видатна швидкість сортування підрахунком досягається за рахунок того,


що при цьому не використовуються операції порівняння. Без
використання операцій порівняння, алгоритм сортування підрахунком
дозволяє впорядковувати елементи за час порядку O(N).

Ефективність алгоритму падає, якщо попадає декілька різних елементів в


одну комірку, бо їх треба додатково сортувати. Необхідність сортування
всередині комірок позбавляє алгоритм сенсу, так як кожен елемент
доведеться переглядати більше одного разу.

Проблеми можуть виникати, тільки якщо список містить невелике число


різних значень. Наприклад, якщо всі елементи мають одне і те ж значення,
вони всі будуть поміщені в одну комірку. Якщо алгоритм не виявить це,
він знову і знову буде поміщати всі елементи в одину і ту ж комірку,
викликавши нескінченну рекурсію і вичерпавши весь стековий простір.
Застосування даного сортування доцільно використовувати лише тоді,
коли кількість елементів масиву набагато більша за діапазон можливих
значень. Наприклад, мільйон натуральних чисел, менших 100.

8
9.Порівняльна характеристика

Усі алгоритми, які ми досліджували до цього здійснюють сортування,


ґрунтуючись винятково на попарних порівняннях елементів, тому їх іноді
називають сортуваннями порівнянням (comparison sort). Проте будь-який
алгоритм такого типу сортує n елементів за час не менше  (nlogn) у
найгіршому випадку. Таким чином, алгоритми сортування злиттям і за
допомогою купи асимптотично оптимальні: не існує алгоритму
сортування порівнянням, що перевищував би зазначені алгоритми більш
ніж у скінченне число раз.

Зрозуміло, що дані алгоритми поліпшують оцінку  (nlogn) за рахунок


того, що викори- стовують не лише попарні порівняння, але й внутрішню
структуру об'єк- тів, що відсортовуються.

9
1
0

You might also like