Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
103c893
Задание 1
Evgenii-afk Sep 28, 2025
be9052f
задание 1 отдельно графики
Evgenii-afk Sep 28, 2025
587e2fd
задание 1 отдельно графики
Evgenii-afk Sep 28, 2025
7c69c43
add png
Evgenii-afk Sep 28, 2025
d263b6e
same
Evgenii-afk Sep 28, 2025
9f2ef07
add task 2
Evgenii-afk Sep 28, 2025
a347329
Update Untitled.md
Evgenii-afk Sep 28, 2025
e0cd3d6
добавил теорию
Evgenii-afk Sep 29, 2025
91b22e4
добавил табличку
Evgenii-afk Sep 29, 2025
aa4cf77
добавил цели и вывод
Evgenii-afk Sep 29, 2025
356de46
исправил разметку
Evgenii-afk Sep 29, 2025
e7f7c9f
лаба 2 50%
Evgenii-afk Oct 5, 2025
1fefb90
доделал лабу 2
Evgenii-afk Oct 5, 2025
dc6af66
добавил блок схему
Evgenii-afk Oct 5, 2025
a6251be
попавил код
Evgenii-afk Oct 6, 2025
5584a7b
созранение перед LaTex
Evgenii-afk Oct 6, 2025
c866526
Merge branch 'askras:main' into main
Evgenii-afk Oct 6, 2025
934292d
блок схемы
Evgenii-afk Oct 6, 2025
7f296fb
4/6 версий готовы
Evgenii-afk Oct 12, 2025
4a61ba5
доделал
Evgenii-afk Oct 12, 2025
a5bc159
добавил табличку
Evgenii-afk Oct 12, 2025
884ec06
кое что изменлил
Evgenii-afk Oct 13, 2025
c3e5ee6
Update Untitled.md
Evgenii-afk Oct 13, 2025
bbdfaa5
lab 4
Evgenii-afk Oct 19, 2025
761a31f
add two task lab_05
Evgenii-afk Oct 25, 2025
3fd0d0b
lab 5 done
Evgenii-afk Oct 26, 2025
33d6556
done
Evgenii-afk Oct 27, 2025
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
310 changes: 310 additions & 0 deletions labs/lab_01/example/Untitled.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
---
jupyter:
jupytext:
text_representation:
extension: .md
format_name: markdown
format_version: '1.3'
jupytext_version: 1.17.3
kernelspec:
display_name: Python 3 (ipykernel)
language: python
name: python3
---

## Цель работы

Целью данной лабораторной работы является приобретение практических навыков эмпирического анализа временной сложности алгоритмов. Это включает проведение серии экспериментальных замеров времени работы различных алгоритмов при изменении размера входных данных, построение графиков зависимости времени от объема данных, а также проведение теоретического анализа и сопоставление полученных эмпирических результатов с теоретическими оценками временной сложности.


1.2 сумма

```python
import random
import usage_time
import matplotlib.pyplot as plt

def sum_nums(v: list):
total = 0
for num in v:
total += num
return total

items = range(1, 10**5 * (20 - 6), 50000)
func = usage_time.get_usage_time()(sum_nums)
times = [
func([
random.randint(1, 3)
for _ in range(n)
])
for n in items
]

plt.plot(items, times, 'bo-')
ax = plt.gca()

plt.title('The execution time of the sum of list numbers algorithm')
ax.set_xlabel('Number of elements')
ax.set_ylabel('Time, sec')
plt.savefig('sum.png')
plt.show()

```

![](images/sum.png)

1.3 произведение эллементов

```python

```

```python
import random, usage_time
import matplotlib.pyplot as plt


def multiplication_nums(v: list):
mult = 1.0
for num in v:
mult *= num
return mult


items = range(1, 10**5 * (20 - 6), 50000)
func = usage_time.get_usage_time()(multiplication_nums)
times = [
func([
random.randint(1, 3)
for _ in range(n)
])
for n in items
]

fig = plt.plot(items, times, 'bo-')
ax = plt.gca()

plt.title('The execution time of the get multiplication of list numbers algorithm')
ax.set_xlabel('Number of elements')
ax.set_ylabel('Time, sec')
plt.savefig('mult.png')
plt.show()
```

![](images/mult.png)

1.6. поиск минимума простым перебором

```python
import random
import usage_time
import matplotlib.pyplot as plt


def get_min(v: list) -> int:
min_num = v[0]
for num in v:
if num < min_num:
min_num = num
return min_num


items = range(1, 10**5 * (20 - 6), 50000)
func = usage_time.get_usage_time()(get_min)
times = [
sum([
func([
random.randint(1, 10)
for _ in range(n)
])
for _ in range(20)
]) / 20
for n in items
]

plt.plot(items, times, 'bo-')
ax = plt.gca()

plt.title('The execution time of the getting min of list numbers algorithm')
ax.set_xlabel('Number of elements')
ax.set_ylabel('Time, sec')
plt.grid(True)
plt.savefig('min.png')
plt.show()
```

![](images/min.png)

1.4. вычисление полинома методом Горнера

```python
import random
import usage_time
import matplotlib.pyplot as plt


def horner(coeffs: list, x: float) -> float:
result = 0
for coef in reversed(coeffs):
result = result * x + coef
return result


items = range(1, 10**5 * (20 - 6), 50000)
func = usage_time.get_usage_time()(horner)

times = [
sum([
func(
[random.random() for _ in range(n)],
random.random()
)
for _ in range(20)
]) / 20
for n in items
]

plt.plot(items, times, 'bo-')
ax = plt.gca()

plt.title('Execution time of polynomial evaluation by Horner\'s method')
ax.set_xlabel('Number of polynomial coefficients')
ax.set_ylabel('Time, sec')
plt.grid(True)
plt.savefig('horn.png')
plt.show()
```
![](images/horn.png)

Задание 2

```python
import random, usage_time
import matplotlib.pyplot as plt


def matrix_mult(matrix_a: list, matrix_b: list):
matrix_c = [
[0 for _ in range(len(matrix_a))]
for _ in range(len(matrix_a))
]

for y in range(len(matrix_a)):
for x in range(len(matrix_a)):
num = 0
for i in range(len(matrix_a)):
num += matrix_a[y][i] * matrix_b[i][x]
matrix_c[y][x] = num
print(len(matrix_a))
return matrix_c


items = range(1, 10**2 * (20 - 6), 100)
func = usage_time.get_usage_time()(matrix_mult)
times = [
func(
[
[
random.randint(1, 3)
for _ in range(n)
]
for _ in range(n)
],
[
[
random.randint(4, 6)
for _ in range(n)
]
for _ in range(n)
]
)
for n in items
]

fig = plt.plot(items, times, 'bo-')
ax = plt.gca()

plt.title('The execution time of the get matrix multiplication of list numbers algorithm')
ax.set_xlabel('Number of elements')
ax.set_ylabel('Time, sec')
plt.savefig('matr.png')
plt.show()
```

![](images/matr.png)


## Контрольные вопросы по вычислительной сложности алгоритмов

1. Вычислительная сложность алгоритма — это характеристика количества ресурсов (времени и памяти), которые требуются алгоритму для обработки данных в зависимости от размера входа. Анализ сложности важен для оценки эффективности алгоритма и прогноза его поведения при большом объеме данных.
2. Время выполнения — сколько времени требуется алгоритму для обработки входных данных. Пространство (память) — сколько памяти алгоритм использует. Иногда приходится жертвовать временем ради уменьшения памяти (например, жадные алгоритмы) или наоборот — использовать больше памяти для ускорения работы (например, хеш-таблицы).
3. Асимптотический анализ изучает поведение алгоритма при больших объемах данных, избавляясь от постоянных и малозначимых факторов. Это удобнее, чем точные замеры в наносекундах, которые сильно зависят от конкретного оборудования и условий выполнения.
4. Нотация «О-большое» (Big O) описывает верхнюю границу времени или памяти, которую может потребовать алгоритм в худшем случае при росте объема данных.
5. Классы сложности (в порядке возрастания):
| Класс сложности | Описание | Пример алгоритма |
| :-- | :-- | :-- |
| O(1) | Константная | Доступ к элементу по индексу |
| O(log n) | Логарифмическая | Бинарный поиск |
| O(n) | Линейная | Простое сканирование массива |
| O(n log n) | Линейно-логарифмическая | Быстрая сортировка (QuickSort) |
| O(n²) | Квадратичная | Сортировка пузырьком |
| O(2ⁿ) | Экспоненциальная | Наивное вычисление Фибоначчи |

6. Сложность фрагментов кода:

- Простой цикл от 0 до n — O(n).
- Два вложенных цикла от 0 до n — O(n²).
- Цикл с удвоением счетчика (i = i * 2) — O(log n).
- Цикл с делением счетчика на 2 (i = i / 2) — O(log n).
- Два независимых цикла подряд — O(n + m), при m=n — O(n).
- Рекурсивная функция, вызывающая себя дважды — O(2ⁿ).

7. Сложность в худшем, среднем и лучшем случае отличается по объему потребляемых ресурсов для разных входных данных. Например, QuickSort имеет O(n²) в худшем (плохой выбор опорного элемента) и O(n log n) в среднем и лучшем.
8. Пространственная сложность — количество дополнительной памяти, используемой алгоритмом. Для рекурсивных функций учитывается память стека вызовов, равная глубине рекурсии.
9. При очень малых n алгоритм с O(2ⁿ) может быть быстрее, чем O(n³), так как для маленьких n экспонента не успеет «выстрелить». Однако для средних и больших n O(n³) рациональнее из-за экспоненциального роста.
10. Временная сложность операций:

| Операция | Сложность |
| :--: | :---: |
| Поиск в неотсортированном массиве | O(n) |
| Поиск в отсортированном массиве | O(log n) |
| Вставка в начало связного списка | O(1) |
| Вставка в хеш-таблицу (ср.случай) | O(1), (худший) O(n) |
| Поиск минимума в мин-куче | O(1) |

11. Сравнение сортировок:

- QuickSort: средний O(n log n), худший O(n²), зависит от выбора опорного элемента.
- MergeSort: всегда O(n log n), но из-за дополнительной памяти и копирования в практике медленнее.
- Insertion Sort: эффективнее MergeSort на почти отсортированных или очень маленьких массивах.

12. Пространственно-временная дилемма — компромисс между временем и памятью, например, использование хеш-таблиц (больше памяти, меньше времени) vs. обход без дополнительной памяти (дольше).
13. NP-полнота — класс задач, решение которых можно проверить за полиномиальное время, но неизвестно, можно ли их решить за полиномиальное время. Класс P — задачи, решаемые за полиномиальное время.
14. Полиномиальное решение одной NP-полной задачи означает, что все NP-полные задачи можно быстро решить — важнейшая проблема теории алгоритмов (P=NP?).
15. NP-полноту доказывают сведением задачи к уже известной NP-полной задаче — так называемое "сведение по Карпу".
16. Омега (Ω) — нижняя оценка, тета (Θ) — точная оценка. В отличии от O, они дают соответственно минимум или точный порядок роста.
17. Сложность определяется по наибольшему слагаемому, так как при больших n остальные становятся несущественными. Константы отбрасываются для удобства анализа.
18. Не всегда. При малых n O(n) может быть быстрее O(log n) из-за констант и накладных расходов.
19. Для анализа можно предложить конкретный код.
20. Поиск двух чисел с суммой X в отсортированном массиве:

- Используем два указателя — один слева, другой справа.
- Если сумма больше X — сдвигаем правый указатель, иначе левый.
- Сложность O(n), память O(1).
- Эффективнее чем полный перебор O(n²).

21. Улучшение алгоритма:

- Пример: из O(n²) сделать O(n) с помощью хеш-таблицы для поиска пар чисел.


## Выводы по лабораторной работе

В ходе лабораторной работы были успешно реализованы замеры времени работы алгоритмов для различных функций и операций на случайных данных разного объема. Полученные эмпирические графики временных затрат в целом соответствуют ожидаемым теоретическим оценкам асимптотической сложности алгоритмов.

Эксперимент подтвердил, что для алгоритмов с разной сложностью рост времени их исполнения при возрастании размера входных данных соответствует классификации: от константной и линейной до квадратичной и кубической. По мере увеличения объема данных различия во временных сложностях становятся все более очевидными.

Эмпирический анализ показал важность учета практических особенностей исполнения, таких как накладные расходы системы и случайные отклонения времени, что требует усреднения результатов по нескольким запускам.

Таким образом, лабораторная работа продемонстрировала применение эмпирического подхода для оценки временной сложности алгоритмов, что является важным дополнением к теоретическому анализу и помогает лучше понять их поведение на практике.

9 changes: 9 additions & 0 deletions labs/lab_01/example/Untitled1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
jupyter:
jupytext:
text_representation:
extension: .md
format_name: markdown
format_version: '1.3'
jupytext_version: 1.17.3
---
Binary file added labs/lab_01/example/images/horn.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added labs/lab_01/example/images/matr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added labs/lab_01/example/images/min.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added labs/lab_01/example/images/mult.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added labs/lab_01/example/images/sum.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added labs/lab_01/example/mult.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added labs/lab_02/var6/LaTeX/comb_sort.pdf
Binary file not shown.
Binary file added labs/lab_02/var6/LaTeX/comb_sort.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions labs/lab_02/var6/LaTeX/comb_sort.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric, arrows.meta, positioning}

\tikzset{
startstop/.style = {rectangle, rounded corners, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=red!30},
process/.style = {rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=orange!30},
decision/.style = {diamond, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=green!30},
arrow/.style = {thick, -Stealth}
}

\begin{document}
\begin{tikzpicture}[node distance=1.5cm]

% Main algorithm flow
\node (start) [startstop] {Start Comb Sort};
\node (init) [process, below=of start] {gap = n\\shrink = 1.3\\sorted = false};
\node (dec1) [decision, below=of init] {gap > 1 OR\\not sorted?};
\node (update) [process, below=of dec1] {gap = max(1, floor(gap/shrink))\\sorted = true};
\node (init_i) [process, below=of update] {i = 0};
\node (dec2) [decision, below=of init_i] {i + gap < n?};

% Inner loop - comparison and swap
\node (dec3) [decision, right=2cm of dec2] {array[i] > array[i+gap]?};
\node (swap) [process, below=of dec3] {Swap array[i] and array[i+gap]\\sorted = false};
\node (increment) [process, below=2cm of dec2] {i = i + 1};
\node (stop) [startstop, below=2.5cm of dec1] {End};

% Connections - main flow
\draw [arrow] (start) -- (init);
\draw [arrow] (init) -- (dec1);
\draw [arrow] (dec1) -- node[right] {Yes} (update);
\draw [arrow] (update) -- (init_i);
\draw [arrow] (init_i) -- (dec2);

% Connections - inner loop
\draw [arrow] (dec2) -- node[above] {Yes} (dec3);
\draw [arrow] (dec3) -- node[right] {Yes} (swap);
\draw [arrow] (swap) |- (increment);

% Connections - no swap path
\draw [arrow] (dec3.east) -- ++(0.5,0) node[above] {No} |- (increment.east);

% Connections - loop back
\draw [arrow] (increment.west) -| node[below left] {Continue inner loop} ([xshift=-1cm]dec2.west) -- (dec2.west);

% Connections - exit conditions
\draw [arrow] (dec2.south) -- node[left] {No} (increment.north);
\draw [arrow] (increment.south) -- ++(0,-0.5) -| node[below right] {Next iteration} ([xshift=1cm]dec1.east) -- (dec1.east);

\draw [arrow] (dec1.west) -- node[above] {No} ++(-2,0) |- (stop.west);

\end{tikzpicture}
\end{document}
Binary file added labs/lab_02/var6/LaTeX/radix_sort.pdf
Binary file not shown.
Binary file added labs/lab_02/var6/LaTeX/radix_sort.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading