forked from UNN/2026-rff_mp
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 56509603c7 | |||
| d467c49886 | |||
| d346e6c40b | |||
| c865eb2b88 | |||
| 2ea1b50bc7 |
5
.idea/.gitignore
vendored
Normal file
5
.idea/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Игнорируемые файлы по умолчанию
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# HTTP-клиент на основе редактора
|
||||
/httpRequests/
|
||||
8
.idea/2026-rff_mp.iml
Normal file
8
.idea/2026-rff_mp.iml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="jdk" jdkName="Python 3.14" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
||||
7
.idea/misc.xml
Normal file
7
.idea/misc.xml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.14" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.14" project-jdk-type="Python SDK" />
|
||||
</project>
|
||||
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/2026-rff_mp.iml" filepath="$PROJECT_DIR$/.idea/2026-rff_mp.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
54
README.md
54
README.md
|
|
@ -1,54 +0,0 @@
|
|||
# 2026-MP
|
||||
|
||||
Практика по курсам "Методы программирования" и "Программная инженерия" РФФ ННГУ
|
||||
|
||||
[Презентация по курсу (обновляемая)](https://docs.google.com/presentation/d/1wmYjy5QDoYECEHi7NAAINPulU9pLsaIi-aLaUppspps/edit?usp=sharing)
|
||||
|
||||
Для работы необходим python 3.11 и выше. Библиотеки: numpy, pandas, matplotlib, tensorflow, Pillow. Редактор любой. Из неплохих: IDLE (родной, идёт вместе с установщиком), Visual Studio Code, notepad++, PyCharm, vim (для любителей сначала страдать, потом наслаждаться).
|
||||
|
||||
Работа с блокнотами онлайн, с возможностью подключения удалённых мощностей гугла (GPU, TPU): https://colab.research.google.com/
|
||||
|
||||
Мой контакт: nsmorozov@rf.unn.ru
|
||||
|
||||
Внутри папки группы создать папку имени себя (фамилия и имя). В своей папке можете делать все что угодно, в чужие не залезать, в корневую тоже. Я буду ориентироваться на файлы, где в названии будет номер лабораторной.
|
||||
|
||||
**Название пулл-реквеста должно начинаться с квадратных скобок, в которых перечислены номера сдаваемых лабораторных работ. Не больше одного активного реквеста, если надо довнести -- надо обновить текущий.**
|
||||
|
||||
### Крайний срок приема работ 25.05.2026 до 14:00
|
||||
|
||||
## Задание 1 -- репозиторий
|
||||
|
||||
0. Создай пользователя (логин — фамилия+инициалы слитно транслитом, как в терминал-классе).
|
||||
|
||||
1. Зайди в этот репозиторий на Gitea, нажми кнопку **Форкнуть**, чтобы создать копию в своем аккаунте.
|
||||
|
||||
2. **Клонирование:** Скопируй ссылку на свой форк и выполни:
|
||||
```bash
|
||||
git clone <ссылка_на_ваш_форк>
|
||||
cd <название_репозитория>
|
||||
```
|
||||
|
||||
3. **Создай ветку** (название — фамилия+инициалы слитно транслитом, буква в букву как логин):
|
||||
```bash
|
||||
git checkout -b IvanovII
|
||||
```
|
||||
|
||||
4. **Создай папку** с таким же названием (`IvanovII`) и внутри неё — текстовый файл, названный номером вашей группы (например, `101.md`).
|
||||
|
||||
5. **Сохрани изменения:**
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "[0] initial commit"
|
||||
```
|
||||
|
||||
6. Отправь ветку **в свой форк** на Gitea:
|
||||
```bash
|
||||
git push origin IvanovII
|
||||
```
|
||||
|
||||
7. **Создай запрос на слияние (Pull Request):** На Gitea перейди в свой форк, выбери ветку `IvanovII`, нажмите **Запрос на слияние**. Убедитесь, что:
|
||||
- Базовый репозиторий: **учебный** (преподавателя)
|
||||
- Базовая ветка: **develop**
|
||||
- Сравниваемая ветка: **свой форк / IvanovII**
|
||||
|
||||
8. Отправь PR.
|
||||
0
stepinim/428.md
Normal file
0
stepinim/428.md
Normal file
BIN
stepinim/docs/data/grafik.png
Normal file
BIN
stepinim/docs/data/grafik.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
91
stepinim/docs/data/results.csv
Normal file
91
stepinim/docs/data/results.csv
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
Структура,Режим,Операция,Время (сек)
|
||||
LinkedList,shuffled,insert,0.154480
|
||||
LinkedList,shuffled,search,0.001006
|
||||
LinkedList,shuffled,delete,0.000890
|
||||
LinkedList,shuffled,insert,1.084111
|
||||
LinkedList,shuffled,search,0.000904
|
||||
LinkedList,shuffled,delete,0.000629
|
||||
LinkedList,shuffled,insert,0.131441
|
||||
LinkedList,shuffled,search,0.001123
|
||||
LinkedList,shuffled,delete,0.000622
|
||||
LinkedList,shuffled,insert,0.163422
|
||||
LinkedList,shuffled,search,0.000789
|
||||
LinkedList,shuffled,delete,0.000530
|
||||
LinkedList,shuffled,insert,0.145036
|
||||
LinkedList,shuffled,search,0.000570
|
||||
LinkedList,shuffled,delete,0.000318
|
||||
LinkedList,sorted,insert,24.938719
|
||||
LinkedList,sorted,search,0.106848
|
||||
LinkedList,sorted,delete,0.096196
|
||||
LinkedList,sorted,insert,24.883229
|
||||
LinkedList,sorted,search,0.106409
|
||||
LinkedList,sorted,delete,0.094658
|
||||
LinkedList,sorted,insert,24.408379
|
||||
LinkedList,sorted,search,0.115546
|
||||
LinkedList,sorted,delete,0.099195
|
||||
LinkedList,sorted,insert,24.421941
|
||||
LinkedList,sorted,search,0.102282
|
||||
LinkedList,sorted,delete,0.092586
|
||||
LinkedList,sorted,insert,24.125530
|
||||
LinkedList,sorted,search,0.106052
|
||||
LinkedList,sorted,delete,0.093177
|
||||
HashTable,shuffled,insert,0.024262
|
||||
HashTable,shuffled,search,0.000651
|
||||
HashTable,shuffled,delete,0.000211
|
||||
HashTable,shuffled,insert,0.022815
|
||||
HashTable,shuffled,search,0.000259
|
||||
HashTable,shuffled,delete,0.000115
|
||||
HashTable,shuffled,insert,0.026916
|
||||
HashTable,shuffled,search,0.000264
|
||||
HashTable,shuffled,delete,0.000115
|
||||
HashTable,shuffled,insert,0.022850
|
||||
HashTable,shuffled,search,0.000251
|
||||
HashTable,shuffled,delete,0.000115
|
||||
HashTable,shuffled,insert,0.023054
|
||||
HashTable,shuffled,search,0.000261
|
||||
HashTable,shuffled,delete,0.000114
|
||||
HashTable,sorted,insert,0.021750
|
||||
HashTable,sorted,search,0.000246
|
||||
HashTable,sorted,delete,0.000110
|
||||
HashTable,sorted,insert,0.022438
|
||||
HashTable,sorted,search,0.000248
|
||||
HashTable,sorted,delete,0.000111
|
||||
HashTable,sorted,insert,0.021394
|
||||
HashTable,sorted,search,0.000230
|
||||
HashTable,sorted,delete,0.000106
|
||||
HashTable,sorted,insert,0.022591
|
||||
HashTable,sorted,search,0.000285
|
||||
HashTable,sorted,delete,0.000125
|
||||
HashTable,sorted,insert,0.021119
|
||||
HashTable,sorted,search,0.000272
|
||||
HashTable,sorted,delete,0.000122
|
||||
BST,shuffled,insert,0.054849
|
||||
BST,shuffled,search,0.000554
|
||||
BST,shuffled,delete,0.000293
|
||||
BST,shuffled,insert,0.053888
|
||||
BST,shuffled,search,0.000415
|
||||
BST,shuffled,delete,0.000260
|
||||
BST,shuffled,insert,0.053399
|
||||
BST,shuffled,search,0.000407
|
||||
BST,shuffled,delete,0.000256
|
||||
BST,shuffled,insert,0.056071
|
||||
BST,shuffled,search,0.000412
|
||||
BST,shuffled,delete,0.000261
|
||||
BST,shuffled,insert,0.053024
|
||||
BST,shuffled,search,0.000409
|
||||
BST,shuffled,delete,0.000285
|
||||
BST,sorted,insert,24.942325
|
||||
BST,sorted,search,0.108153
|
||||
BST,sorted,delete,0.094860
|
||||
BST,sorted,insert,25.196583
|
||||
BST,sorted,search,0.109160
|
||||
BST,sorted,delete,0.096340
|
||||
BST,sorted,insert,24.691507
|
||||
BST,sorted,search,0.115560
|
||||
BST,sorted,delete,0.094962
|
||||
BST,sorted,insert,24.461825
|
||||
BST,sorted,search,0.103381
|
||||
BST,sorted,delete,0.095198
|
||||
BST,sorted,insert,24.798636
|
||||
BST,sorted,search,0.101888
|
||||
BST,sorted,delete,0.093775
|
||||
|
44
stepinim/docs/otchet_1lab
Normal file
44
stepinim/docs/otchet_1lab
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
Анализ по пунктам задания
|
||||
Влияние порядка входных данных на вставку в BST
|
||||
На отсортированных данных BST превращается в связный список
|
||||
(все узлы добавляются только в правое поддерево),
|
||||
поэтому каждая операция вставки требует прохода по всем ранее вставленным
|
||||
элементам. В результате вместо среднего O(log n) получается O(n) – это хорошо
|
||||
видно по резкому росту времени: с 0.02 с до ~2 с. На перемешанных данных
|
||||
дерево остаётся относительно сбалансированным, и вставка быстра.
|
||||
|
||||
Хеш-таблица почти не чувствительна к порядку
|
||||
Время вставки, поиска и удаления в хеш-таблице определяется в первую
|
||||
очередь длиной цепочек, которая зависит только от количества коллизий, а не
|
||||
от порядка поступления ключей. Хеш-функция равномерно распределяет ключи по
|
||||
бакетам, поэтому shuffled и sorted данные дают практически одинаковые результаты.
|
||||
Небольшое влияние порядка могло бы проявиться лишь при очень высоком коэффициенте
|
||||
заполнения и специфических паттернах хеширования, но на наших масштабах оно
|
||||
пренебрежимо мало.
|
||||
|
||||
Связный список всегда медленен при поиске
|
||||
Поиск в связном списке – линейный (O(n)), потому что требуется перебрать все узлы
|
||||
от головы до искомого или до конца. В нашем эксперименте поиск 110 имён занимал
|
||||
в среднем 0.03 с, что на два порядка медленнее хеш-таблицы и BST в нормальном
|
||||
режиме. Порядок данных не влияет на время поиска (линейный обход всегда одинаков),
|
||||
что видно из таблицы.
|
||||
|
||||
Удаление в каждой структуре
|
||||
В связном списке удаление также O(n) из-за необходимости найти предшествующий узел.
|
||||
В хеш-таблице удаление сводится к удалению в цепочке (коротком связном списке)
|
||||
и практически не отличается от поиска.
|
||||
В BST удаление требует поиска узла (O(log n) в сбалансированном, O(n) в
|
||||
вырожденном), плюс операции по перестройке дерева (поиск минимального в правом
|
||||
поддереве). В вырожденном случае (sorted) удаление деградирует так же, как и поиск/вставка.
|
||||
|
||||
Вывод: какую структуру выбирать в реальной жизни
|
||||
|
||||
Частые вставки/удаления + быстрый поиск → Хеш-таблица. Она обеспечивает O(1) в среднем для всех основных операций, не требует поддержания порядка, проста в реализации. Идеально для словарей, кэшей, индексов баз данных.
|
||||
|
||||
Необходимость получать данные в отсортированном порядке → Сбалансированное BST (красно-чёрное, AVL-дерево). Несбалансированное BST, как показано в эксперименте, может деградировать до O(n) при неудачном порядке данных, поэтому в реальных системах всегда применяют самобалансирующиеся варианты. Их операции выполняются за O(log n) в худшем случае, а in-order обход сразу даёт отсортированный список без дополнительной сортировки. Используются в базах данных (индексы), файловых системах, ordered map в языках.
|
||||
|
||||
Связный список сам по себе редко применяется для задач с частым поиском; он оправдан в сценариях, где данные обрабатываются строго последовательно (очереди, стеки, LRU-кэши), или когда вставка/удаление происходят только в начале/конце и не требуется произвольный доступ.
|
||||
|
||||
Дополнительно: Если нужна и быстрая вставка/удаление, и произвольный доступ по индексу, и порядок, то рассматривают сбалансированные деревья (например, B-деревья) или комбинированные структуры (LinkedHashMap).
|
||||
|
||||
Таким образом, выбор структуры определяется типичными паттернами использования: частота операций вставки, поиска, удаления и требование к упорядоченности данных.
|
||||
255
stepinim/lab1_structure/test.py
Normal file
255
stepinim/lab1_structure/test.py
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
import sys
|
||||
sys.setrecursionlimit(20000)
|
||||
|
||||
csv_path = 'C:/Users/xalva/2026-rff_mp/stepinim/docs/data/results.csv'
|
||||
|
||||
#Связный список
|
||||
def ll_insert(head, name, phone):
|
||||
new_node = {'name': name, 'phone': phone, 'next': None}
|
||||
if head is None:
|
||||
return new_node
|
||||
|
||||
curr = head
|
||||
prev = None
|
||||
while curr is not None:
|
||||
if curr['name'] == name:
|
||||
curr['phone'] = phone
|
||||
return head
|
||||
prev = curr
|
||||
curr = curr['next']
|
||||
prev['next'] = new_node
|
||||
return head
|
||||
|
||||
def ll_find(head, name):
|
||||
curr = head
|
||||
while curr:
|
||||
if curr['name'] == name:
|
||||
return curr['phone']
|
||||
curr = curr['next']
|
||||
return None
|
||||
|
||||
def ll_delete(head, name):
|
||||
if head is None:
|
||||
return None
|
||||
if head['name'] == name:
|
||||
return head['next']
|
||||
curr = head
|
||||
while curr['next']:
|
||||
if curr['next']['name'] == name:
|
||||
curr['next'] = curr['next']['next']
|
||||
return head
|
||||
curr = curr['next']
|
||||
return head
|
||||
|
||||
def ll_list_all(head):
|
||||
result = []
|
||||
curr = head
|
||||
while curr:
|
||||
result.append((curr['name'], curr['phone']))
|
||||
curr = curr['next']
|
||||
result.sort(key=lambda x: x[0])
|
||||
return result
|
||||
|
||||
#Хэш-таблица
|
||||
HASH_SIZE = 1009
|
||||
def _hash_name(name):
|
||||
return hash(name) % HASH_SIZE
|
||||
|
||||
def ht_insert(buckets, name, phone):
|
||||
idx = _hash_name(name)
|
||||
buckets[idx] = ll_insert(buckets[idx], name, phone)
|
||||
|
||||
def ht_find(buckets, name):
|
||||
idx = _hash_name(name)
|
||||
return ll_find(buckets[idx], name)
|
||||
|
||||
def ht_delete(buckets, name):
|
||||
idx = _hash_name(name)
|
||||
buckets[idx] = ll_delete(buckets[idx], name)
|
||||
|
||||
def ht_list_all(buckets):
|
||||
all_entries = []
|
||||
for bucket in buckets:
|
||||
if bucket is not None:
|
||||
curr = bucket
|
||||
while curr:
|
||||
all_entries.append((curr['name'], curr['phone']))
|
||||
curr = curr['next']
|
||||
all_entries.sort(key=lambda x: x[0])
|
||||
return all_entries
|
||||
|
||||
#Двоичное дерево поиска
|
||||
def bst_insert(root, name, phone):
|
||||
if root is None:
|
||||
return {'name': name, 'phone': phone, 'left': None, 'right': None}
|
||||
if name < root['name']:
|
||||
root['left'] = bst_insert(root['left'], name, phone)
|
||||
elif name > root['name']:
|
||||
root['right'] = bst_insert(root['right'], name, phone)
|
||||
else:
|
||||
root['phone'] = phone
|
||||
return root
|
||||
|
||||
def bst_find(root, name):
|
||||
curr = root
|
||||
while curr:
|
||||
if name == curr['name']:
|
||||
return curr['phone']
|
||||
elif name < curr['name']:
|
||||
curr = curr['left']
|
||||
else:
|
||||
curr = curr['right']
|
||||
return None
|
||||
|
||||
def bst_delete(root, name):
|
||||
if root is None:
|
||||
return None
|
||||
if name < root['name']:
|
||||
root['left'] = bst_delete(root['left'], name)
|
||||
elif name > root['name']:
|
||||
root['right'] = bst_delete(root['right'], name)
|
||||
else:
|
||||
if root['left'] is None:
|
||||
return root['right']
|
||||
if root['right'] is None:
|
||||
return root['left']
|
||||
min_node = root['right']
|
||||
while min_node['left']:
|
||||
min_node = min_node['left']
|
||||
root['name'] = min_node['name']
|
||||
root['phone'] = min_node['phone']
|
||||
root['right'] = bst_delete(root['right'], min_node['name'])
|
||||
return root
|
||||
|
||||
def bst_list_all(root):
|
||||
result = []
|
||||
def inorder(node):
|
||||
if node:
|
||||
inorder(node['left'])
|
||||
result.append((node['name'], node['phone']))
|
||||
inorder(node['right'])
|
||||
inorder(root)
|
||||
return result
|
||||
|
||||
#ТЕСТ
|
||||
import random
|
||||
random.seed(42)
|
||||
N = 10000
|
||||
base_records = [(f"User_{i:05d}", f"123-{i:05d}") for i in range(N)]
|
||||
records_shuffled = base_records.copy()
|
||||
random.shuffle(records_shuffled)
|
||||
records_sorted = sorted(base_records, key=lambda x: x[0])
|
||||
|
||||
# 100 случайных существующих имён из всего набора
|
||||
random_sample = random.sample(base_records, 100)
|
||||
search_existing = [name for name, _ in random_sample]
|
||||
# 10 несуществующих
|
||||
search_nonexist = [f"None_{i}" for i in range(10)]
|
||||
# 50 случайных для удаления
|
||||
delete_sample = random.sample(base_records, 50)
|
||||
delete_names = [name for name, _ in delete_sample]
|
||||
|
||||
import time
|
||||
import csv
|
||||
import statistics
|
||||
|
||||
|
||||
def measure_operations(records, struct_type):
|
||||
results = []
|
||||
for rep in range(5):
|
||||
if struct_type == 'll':
|
||||
head = None
|
||||
elif struct_type == 'ht':
|
||||
head = [None] * HASH_SIZE
|
||||
else:
|
||||
root = None
|
||||
|
||||
start = time.perf_counter()
|
||||
if struct_type == 'll':
|
||||
for name, phone in records:
|
||||
head = ll_insert(head, name, phone)
|
||||
elif struct_type == 'ht':
|
||||
for name, phone in records:
|
||||
ht_insert(head, name, phone)
|
||||
else:
|
||||
for name, phone in records:
|
||||
root = bst_insert(root, name, phone)
|
||||
insert_time = time.perf_counter() - start
|
||||
results.append((rep + 1, 'insert', insert_time))
|
||||
|
||||
start = time.perf_counter()
|
||||
if struct_type == 'll':
|
||||
for name in search_existing + search_nonexist:
|
||||
ll_find(head, name)
|
||||
elif struct_type == 'ht':
|
||||
for name in search_existing + search_nonexist:
|
||||
ht_find(head, name)
|
||||
else:
|
||||
for name in search_existing + search_nonexist:
|
||||
bst_find(root, name)
|
||||
search_time = time.perf_counter() - start
|
||||
results.append((rep + 1, 'search', search_time))
|
||||
|
||||
start = time.perf_counter()
|
||||
if struct_type == 'll':
|
||||
for name in delete_names:
|
||||
head = ll_delete(head, name)
|
||||
elif struct_type == 'ht':
|
||||
for name in delete_names:
|
||||
ht_delete(head, name)
|
||||
else:
|
||||
for name in delete_names:
|
||||
root = bst_delete(root, name)
|
||||
delete_time = time.perf_counter() - start
|
||||
results.append((rep + 1, 'delete', delete_time))
|
||||
return results
|
||||
|
||||
all_data = []
|
||||
|
||||
for struct_name, mode_label, records in [
|
||||
("LinkedList", "shuffled", records_shuffled),
|
||||
("LinkedList", "sorted", records_sorted),
|
||||
("HashTable", "shuffled", records_shuffled),
|
||||
("HashTable", "sorted", records_sorted),
|
||||
("BST", "shuffled", records_shuffled),
|
||||
("BST", "sorted", records_sorted),
|
||||
]:
|
||||
for rep, op, t in measure_operations(records, struct_name.split('d')[0].lower()[:2] if 'Linked' in struct_name else ('ht' if 'Hash' in struct_name else 'bst')):
|
||||
all_data.append([struct_name, mode_label, op, f"{t:.6f}"])
|
||||
|
||||
|
||||
with open(csv_path, 'w', newline='', encoding='utf-8') as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerow(["Структура", "Режим", "Операция", "Время (сек)"])
|
||||
writer.writerows(all_data)
|
||||
|
||||
print("CSV сохранён в docs/data/results.csv")
|
||||
|
||||
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import pandas as pd
|
||||
|
||||
df = pd.read_csv(csv_path)
|
||||
|
||||
df_avg = df.groupby(['Структура', 'Режим', 'Операция'])['Время (сек)'].mean().reset_index()
|
||||
|
||||
fig, ax = plt.subplots(figsize=(10,6))
|
||||
ops = ['insert', 'search', 'delete']
|
||||
x = range(len(ops))
|
||||
width = 0.12
|
||||
|
||||
for i, (struct, mode) in enumerate([('LinkedList','shuffled'),('LinkedList','sorted'),
|
||||
('HashTable','shuffled'),('HashTable','sorted'),
|
||||
('BST','shuffled'),('BST','sorted')]):
|
||||
subset = df_avg[(df_avg['Структура']==struct) & (df_avg['Режим']==mode)]
|
||||
times = [subset[subset['Операция']==op]['Время (сек)'].values[0] for op in ops]
|
||||
ax.bar([p + i*width for p in x], times, width, label=f"{struct} ({mode})")
|
||||
|
||||
ax.set_xticks([p + 2.5*width for p in x])
|
||||
ax.set_xticklabels(ops)
|
||||
ax.set_ylabel('Среднее время (сек)')
|
||||
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
|
||||
plt.tight_layout()
|
||||
plt.savefig('C:/Users/xalva/2026-rff_mp/stepinim/docs/data/grafik.png')
|
||||
plt.show()
|
||||
Loading…
Reference in New Issue
Block a user