diff --git a/GutovVM/docs/data/lab_1_data/graphics1-1.py b/GutovVM/docs/data/lab_1_data/graphics1-1.py new file mode 100644 index 0000000..e27789c --- /dev/null +++ b/GutovVM/docs/data/lab_1_data/graphics1-1.py @@ -0,0 +1,57 @@ +#Графики +import csv +import matplotlib.pyplot as plt + +data = [] + +with open('results.csv', 'r') as f: + reader = csv.reader(f) + for row in reader: + data.append(row) + +print(data) + +types = ["shuffled","sorted"] +algorythms = ['Linked list','Hash-table','BST'] +operations = ['Insert','Find','Delete'] +for dt in types: + + for ot in operations: + + X = algorythms + Y = [0.,0.,0.] + + for row in data: + if row[1] == dt and row[2] == ot: + if row[0] == X[0]: + Y[0] = float(row[3]) + elif row[0] == X[1]: + Y[1] = float(row[3]) + elif row[0] == X[2]: + Y[2] = float(row[3]) + + plt.bar(X,Y) + plt.title(dt + ot) + plt.ylabel('Время') + plt.show() + +for dt in types: + + for at in algorythms: + + X = operations + Y = [0.,0.,0.] + + for row in data: + if row[1] == dt and row[0] == at: + if row[2] == X[0]: + Y[0] = float(row[3]) + elif row[2] == X[1]: + Y[1] = float(row[3]) + elif row[2] == X[2]: + Y[2] = float(row[3]) + + plt.bar(X,Y,color='g') + plt.title(dt + at) + plt.ylabel('Время') + plt.show() \ No newline at end of file diff --git a/GutovVM/docs/data/lab_1_data/graphics1-2.py b/GutovVM/docs/data/lab_1_data/graphics1-2.py new file mode 100644 index 0000000..b126811 --- /dev/null +++ b/GutovVM/docs/data/lab_1_data/graphics1-2.py @@ -0,0 +1,58 @@ +#Графики через ln +import csv +import matplotlib.pyplot as plt +import numpy as np + +data = [] + +with open('results.csv', 'r') as f: + reader = csv.reader(f) + for row in reader: + data.append(row) + +print(data) + +types = ["shuffled","sorted"] +algorythms = ['Linked list','Hash-table','BST'] +operations = ['Insert','Find','Delete'] +for dt in types: + + for ot in operations: + + X = algorythms + Y = [0.,0.,0.] + + for row in data: + if row[1] == dt and row[2] == ot: + if row[0] == X[0]: + Y[0] = np.log(float(row[3])) + elif row[0] == X[1]: + Y[1] = np.log(float(row[3])) + elif row[0] == X[2]: + Y[2] = np.log(float(row[3])) + + plt.bar(X,Y) + plt.title(dt + ot) + plt.ylabel('Время') + plt.show() + +for dt in types: + + for at in algorythms: + + X = operations + Y = [0.,0.,0.] + + for row in data: + if row[1] == dt and row[0] == at: + if row[2] == X[0]: + Y[0] = np.log(float(row[3])) + elif row[2] == X[1]: + Y[1] = np.log(float(row[3])) + elif row[2] == X[2]: + Y[2] = np.log(float(row[3])) + + plt.bar(X,Y,color='g') + plt.title(dt + at) + plt.ylabel('Время') + plt.show() \ No newline at end of file diff --git a/GutovVM/docs/data/lab_1_data/log.txt b/GutovVM/docs/data/lab_1_data/log.txt new file mode 100644 index 0000000..8b8adcb --- /dev/null +++ b/GutovVM/docs/data/lab_1_data/log.txt @@ -0,0 +1,176 @@ +Данный файл был создан в ручную копированием данных выводимых программой main при последнем запуске. + +Linked list + + +ll_insert test + +{'name': 'Andrey', 'phone': '7-234-246', 'next': None} +{'name': 'Andrey', 'phone': '7-234-246', 'next': {'name': 'Ivan', 'phone': '6-352-095', 'next': None}} +{'name': 'Andrey', 'phone': '5-257-098', 'next': {'name': 'Ivan', 'phone': '6-352-095', 'next': None}} +{'name': 'Andrey', 'phone': '5-257-098', 'next': {'name': 'Ivan', 'phone': '6-352-095', 'next': {'name': 'Igor', 'phone': '1-374-098', 'next': None}}} +{'name': 'Andrey', 'phone': '5-257-098', 'next': {'name': 'Ivan', 'phone': '6-352-095', 'next': {'name': 'Igor', 'phone': '1-374-098', 'next': {'name': 'Nagibator3000', 'phone': '9-387-098', 'next': None}}}} +{'name': 'Andrey', 'phone': '5-257-098', 'next': {'name': 'Ivan', 'phone': '6-352-095', 'next': {'name': 'Igor', 'phone': '1-374-098', 'next': {'name': 'Nagibator3000', 'phone': '9-387-098', 'next': {'name': 'Sberbank', 'phone': '5-135-357', 'next': None}}}}} +{'name': 'Andrey', 'phone': '5-257-098', 'next': {'name': 'Ivan', 'phone': '6-352-095', 'next': {'name': 'Igor', 'phone': '1-374-098', 'next': {'name': 'Nagibator3000', 'phone': '9-387-098', 'next': {'name': 'Sberbank', 'phone': '5-135-357', 'next': {'name': 'Loshped', 'phone': '0-000-000', 'next': None}}}}}} + +test end + + +ll_find test + +6-352-095 +5-257-098 +5-135-357 +9-387-098 +None + +test_end + + +ll_delete test + +{'name': 'Andrey', 'phone': '5-257-098', 'next': {'name': 'Ivan', 'phone': '6-352-095', 'next': {'name': 'Igor', 'phone': '1-374-098', 'next': {'name': 'Sberbank', 'phone': '5-135-357', 'next': {'name': 'Loshped', 'phone': '0-000-000', 'next': None}}}}} +{'name': 'Andrey', 'phone': '5-257-098', 'next': {'name': 'Ivan', 'phone': '6-352-095', 'next': {'name': 'Igor', 'phone': '1-374-098', 'next': {'name': 'Sberbank', 'phone': '5-135-357', 'next': {'name': 'Loshped', 'phone': '0-000-000', 'next': None}}}}} +{'name': 'Andrey', 'phone': '5-257-098', 'next': {'name': 'Ivan', 'phone': '6-352-095', 'next': {'name': 'Igor', 'phone': '1-374-098', 'next': {'name': 'Sberbank', 'phone': '5-135-357', 'next': None}}}} +{'name': 'Andrey', 'phone': '5-257-098', 'next': {'name': 'Ivan', 'phone': '6-352-095', 'next': {'name': 'Igor', 'phone': '1-374-098', 'next': {'name': 'Sberbank', 'phone': '5-135-357', 'next': None}}}} + +test_end + + +ll_list_all test + +[('Andrey', '5-257-098'), ('Igor', '1-374-098'), ('Ivan', '6-352-095'), ('Sberbank', '5-135-357')] + +test_end + + + +Hash Table + + +ht_insert test + +[None, None, None, None, None, None, None, None] +[{'name': 'Andrey', 'phone': '7-234-246', 'next': None}, None, None, None, None, None, None, None] +[{'name': 'Andrey', 'phone': '7-234-246', 'next': None}, None, None, None, None, None, {'name': 'Ivan', 'phone': '6-352-095', 'next': None}, None] +[{'name': 'Andrey', 'phone': '5-257-098', 'next': None}, None, None, None, None, None, {'name': 'Ivan', 'phone': '6-352-095', 'next': None}, None] +[{'name': 'Andrey', 'phone': '5-257-098', 'next': None}, None, None, None, None, None, {'name': 'Ivan', 'phone': '6-352-095', 'next': None}, {'name': 'Igor', 'phone': '1-374-098', 'next': None}] +[{'name': 'Andrey', 'phone': '5-257-098', 'next': None}, None, None, None, {'name': 'Nagibator3000', 'phone': '9-387-098', 'next': None}, None, {'name': 'Ivan', 'phone': '6-352-095', 'next': None}, {'name': 'Igor', 'phone': '1-374-098', 'next': None}] +[{'name': 'Andrey', 'phone': '5-257-098', 'next': None}, None, None, None, {'name': 'Nagibator3000', 'phone': '9-387-098', 'next': None}, {'name': 'Sberbank', 'phone': '5-135-357', 'next': None}, {'name': 'Ivan', 'phone': '6-352-095', 'next': None}, {'name': 'Igor', 'phone': '1-374-098', 'next': None}] +[{'name': 'Andrey', 'phone': '5-257-098', 'next': None}, {'name': 'Loshped', 'phone': '0-000-000', 'next': None}, None, None, {'name': 'Nagibator3000', 'phone': '9-387-098', 'next': None}, {'name': 'Sberbank', 'phone': '5-135-357', 'next': None}, {'name': 'Ivan', 'phone': '6-352-095', 'next': None}, {'name': 'Igor', 'phone': '1-374-098', 'next': None}] + +test end + + +ht_find test + +6-352-095 +5-257-098 +5-135-357 +9-387-098 +None + +test end + + +ht_delete test + +[{'name': 'Andrey', 'phone': '5-257-098', 'next': None}, {'name': 'Loshped', 'phone': '0-000-000', 'next': None}, None, None, None, {'name': 'Sberbank', 'phone': '5-135-357', 'next': None}, {'name': 'Ivan', 'phone': '6-352-095', 'next': None}, {'name': 'Igor', 'phone': '1-374-098', 'next': None}] +[{'name': 'Andrey', 'phone': '5-257-098', 'next': None}, {'name': 'Loshped', 'phone': '0-000-000', 'next': None}, None, None, None, {'name': 'Sberbank', 'phone': '5-135-357', 'next': None}, {'name': 'Ivan', 'phone': '6-352-095', 'next': None}, {'name': 'Igor', 'phone': '1-374-098', 'next': None}] +[{'name': 'Andrey', 'phone': '5-257-098', 'next': None}, None, None, None, None, {'name': 'Sberbank', 'phone': '5-135-357', 'next': None}, {'name': 'Ivan', 'phone': '6-352-095', 'next': None}, {'name': 'Igor', 'phone': '1-374-098', 'next': None}] +[{'name': 'Andrey', 'phone': '5-257-098', 'next': None}, None, None, None, None, {'name': 'Sberbank', 'phone': '5-135-357', 'next': None}, {'name': 'Ivan', 'phone': '6-352-095', 'next': None}, {'name': 'Igor', 'phone': '1-374-098', 'next': None}] + +test_end + + +ht_list_all test + +[('Andrey', '5-257-098'), ('Igor', '1-374-098'), ('Ivan', '6-352-095'), ('Sberbank', '5-135-357')] + +test_end + + + +bst_insert test + +None +{'name': 'Andrey', 'phone': '7-234-246', 'left': None, 'right': None} +{'name': 'Andrey', 'phone': '7-234-246', 'left': {'name': 'Ivan', 'phone': '6-352-095', 'left': None, 'right': None}, 'right': None} +{'name': 'Andrey', 'phone': '5-257-098', 'left': {'name': 'Ivan', 'phone': '6-352-095', 'left': None, 'right': None}, 'right': None} +{'name': 'Andrey', 'phone': '5-257-098', 'left': {'name': 'Ivan', 'phone': '6-352-095', 'left': None, 'right': {'name': 'Igor', 'phone': '1-374-098', 'left': None, 'right': None}}, 'right': None} +{'name': 'Andrey', 'phone': '5-257-098', 'left': {'name': 'Ivan', 'phone': '6-352-095', 'left': None, 'right': {'name': 'Igor', 'phone': '1-374-098', 'left': None, 'right': None}}, 'right': {'name': 'Nagibator3000', 'phone': '9-387-098', 'left': None, 'right': None}} +{'name': 'Andrey', 'phone': '5-257-098', 'left': {'name': 'Ivan', 'phone': '6-352-095', 'left': None, 'right': {'name': 'Igor', 'phone': '1-374-098', 'left': {'name': 'Sberbank', 'phone': '5-135-357', 'left': None, 'right': None}, 'right': None}}, 'right': {'name': 'Nagibator3000', 'phone': '9-387-098', 'left': None, 'right': None}} +{'name': 'Andrey', 'phone': '5-257-098', 'left': {'name': 'Ivan', 'phone': '6-352-095', 'left': {'name': 'Loshped', 'phone': '0-000-000', 'left': None, 'right': None}, 'right': {'name': 'Igor', 'phone': '1-374-098', 'left': {'name': 'Sberbank', 'phone': '5-135-357', 'left': None, 'right': None}, 'right': None}}, 'right': {'name': 'Nagibator3000', 'phone': '9-387-098', 'left': None, 'right': None}} + +test end + + +bst_find test + +6-352-095 +5-257-098 +5-135-357 +9-387-098 +None + +test end + + +bst_delete test + +{'name': 'Andrey', 'phone': '5-257-098', 'left': {'name': 'Ivan', 'phone': '6-352-095', 'left': {'name': 'Loshped', 'phone': '0-000-000', 'left': None, 'right': None}, 'right': {'name': 'Igor', 'phone': '1-374-098', 'left': {'name': 'Sberbank', 'phone': '5-135-357', 'left': None, 'right': None}, 'right': None}}, 'right': None} +{'name': 'Andrey', 'phone': '5-257-098', 'left': {'name': 'Ivan', 'phone': '6-352-095', 'left': {'name': 'Loshped', 'phone': '0-000-000', 'left': None, 'right': None}, 'right': {'name': 'Igor', 'phone': '1-374-098', 'left': {'name': 'Sberbank', 'phone': '5-135-357', 'left': None, 'right': None}, 'right': None}}, 'right': None} +{'name': 'Ivan', 'phone': '6-352-095', 'left': {'name': 'Loshped', 'phone': '0-000-000', 'left': None, 'right': None}, 'right': {'name': 'Igor', 'phone': '1-374-098', 'left': {'name': 'Sberbank', 'phone': '5-135-357', 'left': None, 'right': None}, 'right': None}} +{'name': 'Ivan', 'phone': '6-352-095', 'left': {'name': 'Loshped', 'phone': '0-000-000', 'left': None, 'right': None}, 'right': {'name': 'Igor', 'phone': '1-374-098', 'left': {'name': 'Sberbank', 'phone': '5-135-357', 'left': None, 'right': None}, 'right': None}} + +test_end + + +bst_list_all test + +[('Loshped', '0-000-000'), ('Ivan', '6-352-095'), ('Sberbank', '5-135-357'), ('Igor', '1-374-098')] + +test_end + + +Итерация 1 +Время Связного Списка: 2.9917209999402985 0.02659020002465695 0.012590099941007793 +Время Хеш-таблицы: 0.005119499983265996 3.9100064896047115e-05 2.0299921743571758e-05 +Время Двоичного Дерева Поиска: 0.09058830002322793 0.00027840002439916134 0.00014549994375556707 +Итерация 2 +Время Связного Списка: 2.903203699970618 0.023054099990986288 0.010875999927520752 +Время Хеш-таблицы: 0.00455170008353889 3.400002606213093e-05 1.9400031305849552e-05 +Время Двоичного Дерева Поиска: 0.03216309996787459 0.00027810002211481333 0.00014749995898455381 +Итерация 3 +Время Связного Списка: 2.921877200016752 0.025615100050345063 0.01236239995341748 +Время Хеш-таблицы: 0.00479620008263737 3.529991954565048e-05 2.0200037397444248e-05 +Время Двоичного Дерева Поиска: 0.03450970002450049 0.0004401999758556485 0.00016369996592402458 +Итерация 4 +Время Связного Списка: 3.003447199938819 0.02533069998025894 0.010745699983090162 +Время Хеш-таблицы: 0.004474699962884188 3.350002225488424e-05 1.8000020645558834e-05 +Время Двоичного Дерева Поиска: 0.07804860000032932 0.00027279998175799847 0.00014109991025179625 +Итерация 5 +Время Связного Списка: 2.9807132000569254 0.0290351000148803 0.013929600012488663 +Время Хеш-таблицы: 0.005072099971584976 5.009991582483053e-05 2.2300053387880325e-05 +Время Двоичного Дерева Поиска: 0.03607590007595718 0.0003352999920025468 0.00016259995754808187 +Итерация 1 +Время Связного Списка: 2.5927454999182373 0.02170580008532852 0.010246100020594895 +Время Хеш-таблицы: 0.00436040002387017 3.50000336766243e-05 1.8999911844730377e-05 +Время Двоичного Дерева Поиска: 0.029087499948218465 0.0003063000040128827 0.00015670002903789282 +Итерация 2 +Время Связного Списка: 2.5688632000237703 0.02236179995816201 0.00998460000846535 +Время Хеш-таблицы: 0.004271199926733971 3.3100019209086895e-05 1.7400016076862812e-05 +Время Двоичного Дерева Поиска: 0.03174210002180189 0.000283299945294857 0.00013529998250305653 +Итерация 3 +Время Связного Списка: 2.6008588999975473 0.019859899999573827 0.010582599905319512 +Время Хеш-таблицы: 0.00447160005569458 3.23000131174922e-05 1.810002140700817e-05 +Время Двоичного Дерева Поиска: 0.03173729998525232 0.0002880999818444252 0.0001452000578865409 +Итерация 4 +Время Связного Списка: 2.5892133000306785 0.022096000029705465 0.010453099966980517 +Время Хеш-таблицы: 0.004718700074590743 3.42000275850296e-05 1.7300015315413475e-05 +Время Двоичного Дерева Поиска: 0.033104100031778216 0.0002930999035015702 0.00015160010661929846 +Итерация 5 +Время Связного Списка: 2.5684097999474034 0.020924199954606593 0.009929200052283704 +Время Хеш-таблицы: 0.0046051000244915485 3.370002377778292e-05 1.8400023691356182e-05 +Время Двоичного Дерева Поиска: 0.03069589997176081 0.0003073000116273761 0.00014600006397813559 +[['Linked list', 'shuffled', 'Insert', '2.9601924599846825'], ['Linked list', 'shuffled', 'Find', '0.02592504001222551'], ['Linked list', 'shuffled', 'Delete', '0.01210075996350497'], ['Hash-table', 'shuffled', 'Insert', '0.004802840016782284'], ['Hash-table', 'shuffled', 'Find', '3.839998971670866e-05'], ['Hash-table', 'shuffled', 'Delete', '2.0040012896060943e-05'], ['BST', 'shuffled', 'Insert', '0.0542771200183779'], ['BST', 'shuffled', 'Find', '0.0003209599992260337'], ['BST', 'shuffled', 'Delete', '0.00015207994729280472'], ['Linked list', 'sorted', 'Insert', '2.5840181399835274'], ['Linked list', 'sorted', 'Find', '0.021389540005475282'], ['Linked list', 'sorted', 'Delete', '0.010239119990728796'], ['Hash-table', 'sorted', 'Insert', '0.004485400021076202'], ['Hash-table', 'sorted', 'Find', '3.3660023473203185e-05'], ['Hash-table', 'sorted', 'Delete', '1.8039997667074203e-05'], ['BST', 'sorted', 'Insert', '0.03127337999176234'], ['BST', 'sorted', 'Find', '0.00029561996925622227'], ['BST', 'sorted', 'Delete', '0.00014696004800498485']] \ No newline at end of file diff --git a/GutovVM/docs/data/lab_1_data/main.py b/GutovVM/docs/data/lab_1_data/main.py new file mode 100644 index 0000000..c4a12e4 --- /dev/null +++ b/GutovVM/docs/data/lab_1_data/main.py @@ -0,0 +1,449 @@ +#LinkedListPhoneBook + +head = None #!!!!!!!!!!!!!! + +print("\nLinked list\n") + +def ll_insert(head, name, phone): + + curr = head + + while curr is not None: + if curr['name'] == name: + curr['phone'] = phone + return head + elif curr['next'] == None: + curr['next'] = {'name' : name, 'phone' : phone, 'next' : None} + return head + curr = curr['next'] + + return {'name' : name, 'phone' : phone, 'next' : None} + + +test_names = ['Andrey', 'Ivan', 'Andrey', 'Igor', 'Nagibator3000', 'Sberbank','Loshped'] +test_phones = ['7-234-246','6-352-095','5-257-098','1-374-098','9-387-098','5-135-357','0-000-000'] + +print("\nll_insert test\n") + +for i in range(len(test_names)): + head = ll_insert(head, test_names[i], test_phones[i]) + print(head) + +print("\ntest end\n\n") + +def ll_find(head, name): + + curr = head + while curr is not None: + if curr['name'] == name: + return curr['phone'] + curr = curr['next'] + + return None + +print('ll_find test\n') + +test_names = ["Ivan", "Andrey", "Sberbank", "Nagibator3000","Ermola"] + +for name in test_names: + print(ll_find(head, name)) + +print('\ntest_end\n\n') + +def ll_delete(head, name): + + if head is not None: + + if head['name'] == name: + return head['next'] + + old_curr = head + curr = head['next'] + + while curr is not None: + if curr['name'] == name: + old_curr['next'] = curr['next'] + break + old_curr, curr = curr, curr['next'] + + return head + +print('ll_delete test\n') + +test_names = ['Nagibator3000','Nagibator3000','Loshped','Ermola'] + +for name in test_names: + head = ll_delete(head, name) + print(head) + + +print('\ntest_end\n\n') + +def ll_list_all(head): + + res = [] + curr = head + + while curr is not None: + res += [(curr['name'],curr['phone'])] + curr = curr['next'] + + return sorted(res) + +print('ll_list_all test\n') + +print(ll_list_all(head)) + +print('\ntest_end\n\n') + + + +#HashTablePhoneBook + +print("\nHash Table\n") + +size = 8 +buckets = [None] * size + +def index(name,size): + return hash(name) % size + +def ht_insert(buckets, name, phone): + ind = index(name, size) + buckets[ind] = ll_insert(buckets[ind], name, phone) + return buckets + +def ht_find(buckets, name): + ind = index(name, size) + return ll_find(buckets[ind], name) + +def ht_delete(buckets, name): + ind = index(name, size) + buckets[ind] = ll_delete(buckets[ind], name) + return buckets + +def ht_list_all(buckets): + res = [] + for head in buckets: + curr = head + while curr is not None: + res += [(curr['name'],curr['phone'])] + curr = curr['next'] + return sorted(res) + +test_names = ['Andrey', 'Ivan', 'Andrey', 'Igor', 'Nagibator3000', 'Sberbank','Loshped'] +test_phones = ['7-234-246','6-352-095','5-257-098','1-374-098','9-387-098','5-135-357','0-000-000'] + +print("\nht_insert test\n") + +print(buckets) +for i in range(len(test_names)): + buckets = ht_insert(buckets, test_names[i], test_phones[i]) + print(buckets) + +print("\ntest end\n\n") + +print("ht_find test\n") + +test_names = ["Ivan", "Andrey", "Sberbank", "Nagibator3000","Ermola"] + +for name in test_names: + print(ht_find(buckets, name)) + +print("\ntest end\n\n") + +print('ht_delete test\n') + +test_names = ['Nagibator3000','Nagibator3000','Loshped','Ermola'] + +for name in test_names: + buckets = ht_delete(buckets, name) + print(buckets) + +print('\ntest_end\n\n') + +print('ht_list_all test\n') + +print(ht_list_all(buckets)) + +print('\ntest_end\n\n') + + + +#BinarySearchTree + +root = None + +def bst_insert(root, name, phone): + + if root == None: + return {'name': name, 'phone': phone, 'left': None, 'right': None} + + elif name == root['name']: + root['phone'] = phone + return root + elif hash(name) < hash(root['name']): + root['left'] = bst_insert(root['left'], name, phone) + return root + else: + root['right'] = bst_insert(root['right'], name, phone) + return root + + +def bst_find(root, name): + + if root == None: + return None + + elif name == root['name']: + return root['phone'] + + elif hash(name) < hash(root['name']): + return bst_find(root['left'],name) + else: + return bst_find(root['right'],name) + + +def bst_delete(root, name): + + if root is None: + return None + elif name == root['name']: + + if root['left'] is None and root['right'] is None: + return None + elif root['left'] is not None and root['right'] is None: + return root['left'] + elif root['right'] is not None and root['left'] is None: + return root['right'] + + curr = root['left'] + oldcurr = root + while curr['right'] is not None: + oldcurr,curr = curr,curr['right'] + + if oldcurr == root: + root['left'] = curr['left'] + else: + oldcurr['right'] = curr['left'] + + curr['left'],curr['right'] = root['left'],root['right'] + return curr + + elif hash(name) < hash(root['name']): + root['left'] = bst_delete(root['left'],name) + return root + else: + root['right'] = bst_delete(root['right'],name) + return root + + +def bst_list_all(root): + + if root is None: + return [] + + return bst_list_all(root['left']) + [(root['name'],root['phone'])] + bst_list_all(root['right']) + + +test_names = ['Andrey', 'Ivan', 'Andrey', 'Igor', 'Nagibator3000', 'Sberbank','Loshped'] +test_phones = ['7-234-246','6-352-095','5-257-098','1-374-098','9-387-098','5-135-357','0-000-000'] + +print("\nbst_insert test\n") + +print(root) +for i in range(len(test_names)): + root = bst_insert(root, test_names[i], test_phones[i]) + print(root) + +print("\ntest end\n\n") + +print("bst_find test\n") + +test_names = ["Ivan", "Andrey", "Sberbank", "Nagibator3000","Ermola"] + +for name in test_names: + print(bst_find(root, name)) + +print("\ntest end\n\n") + +print('bst_delete test\n') + +test_names = ['Nagibator3000','Nagibator3000','Andrey','Ermola'] + +for name in test_names: + root = bst_delete(root, name) + print(root) + +print('\ntest_end\n\n') + +print('bst_list_all test\n') + +print(bst_list_all(root)) + +print('\ntest_end\n\n') + + + +###ЭКСПЕРЕМЕНТАЛЬНАЯ ЧАСТЬ + +#1 Генерация + +import random + +records_shuffled = [] +records_sorted = [] + +N = 10000 + +for i in range(1,N+1): + number = str(random.randint(1,9)) + '-' + str(random.randint(100,999)) + '-' + str(random.randint(100,999)) + '-' + str(random.randint(10,99)) + '-' + str(random.randint(10,99)) + records_sorted += [(f"User_{i:05d}", number)] + +records_shuffled = records_sorted[:] #срезал чтобы не ссылка была +random.shuffle(records_shuffled) + +#2 Инструменты замера времени + +import time + +#start = time.perf_counter() +# ... операции ... +#end = time.perf_counter() +#elapsed = end - start # время в секундах + +results = [] +types = ["shuffled","sorted"] +for dt in range(2): + data = (records_shuffled, records_sorted)[dt] + time_res_sum = [0]*9 + for iteration in range(5): + names = [x for x,_ in data] + test_names = random.sample(names, 150) + + find_names = test_names[0:100] + find_names += [f"None_{i}" for i in range(10)] + + delete_names = test_names[100:150] + + #LinkedList + time_res = [] + + head = None + + + start = time.perf_counter() + + for a in data: + head = ll_insert(head, a[0], a[1]) + + end = time.perf_counter() + time_res.append(end - start) + + + start = time.perf_counter() + + for name in find_names: + ll_find(head, name) + + end = time.perf_counter() + time_res.append(end - start) + + + start = time.perf_counter() + + for name in delete_names: + head = ll_delete(head, name) + + end = time.perf_counter() + time_res.append(end - start) + + #HashTable + size = 15013 #простое число от которого 10000 - это примерно 0.7 (коэффициент заполнения) + buckets = [None] * size + + + start = time.perf_counter() + + for a in data: + buckets = ht_insert(buckets, a[0], a[1]) + + end = time.perf_counter() + time_res.append(end - start) + + + start = time.perf_counter() + + for name in find_names: + ht_find(buckets, name) + + end = time.perf_counter() + time_res.append(end - start) + + + start = time.perf_counter() + + for name in delete_names: + buckets = ht_delete(buckets, name) + + end = time.perf_counter() + time_res.append(end - start) + + #BinarySearchTree + root = None + + + start = time.perf_counter() + + for a in data: + root = bst_insert(root, a[0], a[1]) + + end = time.perf_counter() + time_res.append(end - start) + + + start = time.perf_counter() + + for name in find_names: + bst_find(root, name) + + end = time.perf_counter() + time_res.append(end - start) + + + start = time.perf_counter() + + for name in delete_names: + root = bst_delete(root, name) + + end = time.perf_counter() + time_res.append(end - start) + + print("Итерация ", iteration+1) + print("Время Связного Списка: ", time_res[0], time_res[1], time_res[2]) + print("Время Хеш-таблицы: ", time_res[3], time_res[4], time_res[5]) + print("Время Двоичного Дерева Поиска: ", time_res[6], time_res[7], time_res[8]) + + for i in range(9): + time_res_sum[i] += time_res[i] + + for i in range(9): + time_res_sum[i] /= 5 + + results.append(["Linked list", types[dt], "Insert",str(time_res_sum[0])]) + results.append(["Linked list", types[dt], "Find",str(time_res_sum[1])]) + results.append(["Linked list", types[dt], "Delete",str(time_res_sum[2])]) + results.append(["Hash-table", types[dt], "Insert",str(time_res_sum[3])]) + results.append(["Hash-table", types[dt], "Find",str(time_res_sum[4])]) + results.append(["Hash-table", types[dt], "Delete",str(time_res_sum[5])]) + results.append(["BST", types[dt], "Insert",str(time_res_sum[6])]) + results.append(["BST", types[dt], "Find",str(time_res_sum[7])]) + results.append(["BST", types[dt], "Delete",str(time_res_sum[8])]) + +print(results) + +import csv + +with open("results.csv", "w", newline="") as f: + writer = csv.writer(f) + writer.writerows(results) diff --git a/GutovVM/docs/data/lab_1_data/results.csv b/GutovVM/docs/data/lab_1_data/results.csv new file mode 100644 index 0000000..2667d2e --- /dev/null +++ b/GutovVM/docs/data/lab_1_data/results.csv @@ -0,0 +1,18 @@ +Linked list,shuffled,Insert,2.9601924599846825 +Linked list,shuffled,Find,0.02592504001222551 +Linked list,shuffled,Delete,0.01210075996350497 +Hash-table,shuffled,Insert,0.004802840016782284 +Hash-table,shuffled,Find,3.839998971670866e-05 +Hash-table,shuffled,Delete,2.0040012896060943e-05 +BST,shuffled,Insert,0.0542771200183779 +BST,shuffled,Find,0.0003209599992260337 +BST,shuffled,Delete,0.00015207994729280472 +Linked list,sorted,Insert,2.5840181399835274 +Linked list,sorted,Find,0.021389540005475282 +Linked list,sorted,Delete,0.010239119990728796 +Hash-table,sorted,Insert,0.004485400021076202 +Hash-table,sorted,Find,3.3660023473203185e-05 +Hash-table,sorted,Delete,1.8039997667074203e-05 +BST,sorted,Insert,0.03127337999176234 +BST,sorted,Find,0.00029561996925622227 +BST,sorted,Delete,0.00014696004800498485 diff --git a/GutovVM/docs/data/lab_2_data/expmaze1.txt b/GutovVM/docs/data/lab_2_data/expmaze1.txt new file mode 100644 index 0000000..d4602ae --- /dev/null +++ b/GutovVM/docs/data/lab_2_data/expmaze1.txt @@ -0,0 +1,10 @@ +########## +#S# # +# # #### # +# # # # +### # ## # +# # # +# ##### ## +# # # +##### ##E# +########## \ No newline at end of file diff --git a/GutovVM/docs/data/lab_2_data/expmaze2.txt b/GutovVM/docs/data/lab_2_data/expmaze2.txt new file mode 100644 index 0000000..5d9f4fe --- /dev/null +++ b/GutovVM/docs/data/lab_2_data/expmaze2.txt @@ -0,0 +1,51 @@ +################################################### +#S# # # # # +# # ##### # ######### # ##### # ################# # +# # # # # # # # # # +##### # ########### # ### # ############# ####### # +# # # # # # # # # +# ##### # ############# # # # ############# ##### # +# # # # # # # # # # # +# # ##### # ############# # # # ######### ##### # # +# # # # # # # # # # # # # +# # # ##### # ######### # # ##### ##### ##### # # # +# # # # # # # # # # # # # +# # ######### # ##### ########### # # # # ##### # # +# # # # # # # # # # # +# ############# ### # # ########### ##### # ##### # +# # # # # # # +############### # ### ########### ############### # +# # # # # # # +# ############# ### # # ##### # ######### # ##### # +# # # # # # # # # # # # # # +# # ############# ### # # # # # ####### # # # # # # +# # # # # # # # # # # # +# # ############### # ####### ####### # # ####### # +# # # # # # # # # # +# # # ############# ####### ####### # # ####### # # +# # # # # # # # # # # # +# # # # ######### ####### # # ##### # ####### # # # +# # # # # # # # # # # # # # +##### # # ##### ####### # ##### # # # # ### # ##### +# # # # # # # # # # # # # +# ##### ##### # # ############# # # # ### # ##### # +# # # # # # # # # # # # # +##### ##### # # # # ############# # ### # ##### # # +# # # # # # # # # # # # # +# # ##### # # # # ################### # ### # ### # +# # # # # # # # # # # # # # +# ##### # # # # # # ############### # ### # ### # # +# # # # # # # # # # # # # +##### # ######### ############### # ### # # ### # # +# # # # # # # # # +# ############# ##################### ####### # # # +# # # # # +############# ######################### ########### +# # # # +# ########### # ####################### # ####### # +# # # # # # # +########### # # # ####################### ####### # +# # # # # +# ########### ################################### # +# E# +################################################### \ No newline at end of file diff --git a/GutovVM/docs/data/lab_2_data/expmaze3.txt b/GutovVM/docs/data/lab_2_data/expmaze3.txt new file mode 100644 index 0000000..d80854c --- /dev/null +++ b/GutovVM/docs/data/lab_2_data/expmaze3.txt @@ -0,0 +1,97 @@ +##################################################################################################### +#S# # # # # # +# # ##### # ################# # ######### # ################# # ################################### # +# # # # # # # # # # # # # # +##### # ############# ####### # # ##### # # # ############# # # # ################################# # +# # # # # # # # # # # # # # # # # +# ##### # ############# ####### # # # # # # # # ############# # # # ############################### # +# # # # # # # # # # # # # # # # # # +# # ##### # ######### ########### # # # # # # ############### # # # # ############################# # +# # # # # # # # # # # # # # # # +# # # ##### # ##### ############### ##### ################# # # # # # ############################# # +# # # # # # # # # # # +# # ############# ######################### ############### # ##### # ############################# # +# # # # # # # # # +# ############### # ####################### # ############# # # ##### # ########################### # +# # # # # # # # # # # # +############### # # # ##################### # # ############# # # ##### # ######################### # +# # # # # # # # # # # # # # +# ############# # # # # ################### # # # ############# # # ##### # ####################### # +# # # # # # # # # # # # # # # # # +# # ############# # # # # ################# # # # # ############# # ##### # # ##################### # +# # # # # # # # # # # # # # # # # # +# # # ############# # # # # ############### # # # ############### # ##### # # # ################### # +# # # # # # # # # # # # # # # # +# # # # ############# ##################### # # ######################### # # # # ################# # +# # # # # # # # # # # # # +# # # # # ################################# # ########################### # # # # # ############### # +# # # # # # # # # # # +# # # ####### ############################### ############################# ####### ############### # +# # # # # # # # +# # ######### # ############################# # ########################### ####### # ############# # +# # # # # # # # # # +# ########### # # ########################### # # ######################### ####### # ############# # +# # # # # # # # # # +############# # # # ######################### # ########################### # ##### # ############# # +# # # # # # # # # # # +# ########### # # # # ####################### ############################# # # ##### # ############# +# # # # # # # # # # # # # +# # ######### # # # # # ##################### # ########################### # # # ##### ########### # +# # # # # # # # # # # # # # # # # +# # # ####### # # # # # # ################### # # ######################### # # # # ##### ######### # +# # # # # # # # # # # # # # # # # # # +# # # # ##### # ##### # # # ################# # ########################### # # # # # ##### ####### # +# # # # # # # # # # # # # # # # # # # +# ##### # # # # # ##### # # # ############### ############################# ####### # # ##### ##### # +# # # # # # # # # # # # # # # # # # # +# # ##### # # # # # ##### # # # ############################################# ####### # # # # # ### # +# # # # # # # # # # # # # # # # +# ######### ####### ########### # ############################################# ####### ### # ### # # +# # # # # # # # # # # +########### # ####### ########### # ########################################### ######### # ### # # # +# # # # # # # # # # # # +# ########### # ##### # ########### # ######################################### # ######### ### # # # +# # # # # # # # # # # # # # # # +# # ######### # # # # # # ######### # ######################################### # # ##### ### # # # # +# # # # # # # # # # # # # # # # # # # # # +# # # ####### # # # # # # # ####### # ######################################### # # # # ### # # # # # +# # # # # # # # # # # # # # # # # # # +# ##### ####### ######### # # ##### ########################################### # # # ### # ### # # # +# # # # # # # # # # # # # # # +####### # ############### # # ##### # ######################################### # # ### # ### # # # # +# # # # # # # # # # # # # # # # +# ####### # ############# # ### # ### # ######################################### ### # ### # ### # # +# # # # # # # # # # # # # # # # # +# # ##### # ############### ### # # ### # ######################################### # # ### # ### # # +# # # # # # # # # # # # # # # # # +# # # # ##### ############### # # ##### # # ####################################### # # ### # ### # # +# # # # # # # # # # # # # # # # # +# # # ######### ############# # # # ##### # # ##################################### ##### # ### # # # +# # # # # # # # # # # # # # # +# # ############# ############### # # ##### # # ################################### # ##### ### # # # +# # # # # # # # # # # # # # +# ############### # ############# # # # ##### # # ################################# # # ##### ##### # +# # # # # # # # # # # # # # # +# ################# # ########### # # # # ##### # # ############################### # # # ##### ### # +# # # # # # # # # # # # # # # # # +# # ############### # # ######### # ##### # ##### # # ############################# # # # # ##### # # +# # # # # # # # # # # # # # # # # # +# # # ############# # # # ####### ######### # ##### # # ########################### ####### # ##### # +# # # # # # # # # # # # # # # # # # +# # # # ############# # # # ##### # ####### # # ##### # # ######################### # ####### # ##### +# # # # # # # # # # # # # # # # # # # # # # # +# # # # # ########### # # # # # # # # ##### # # # ##### # # ####################### # # ##### # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# # ##### # ######### # ##### # # # # # # # # # # # ##### # # ##################### # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # +# ######### # ######### ############### ######### # ##### # # ##################### ##### # ##### # # +# # # # # # # # # # # # # # # # +########### # ######### # ##################### # # # ##### # # ################### # ##### # # # # # +# # # # # # # # # # # # # # # # # # +# ####################### # ################### # # # # ##### # # ################# # # ##### # # # # +# # # # # # # # # # # # # # # # # +# # ##################### # # ################# ##### # # ##### # # ############### # # # ##### ### # +# # # # # # # # # # # # # # # # # # # +# # # ################### # # # ############### # ##### # # ##### # # ############# # # # # ##### # # +# # # # # # # # # # # # # # # # E +##################################################################################################### diff --git a/GutovVM/docs/data/lab_2_data/expmaze4.txt b/GutovVM/docs/data/lab_2_data/expmaze4.txt new file mode 100644 index 0000000..3d2a539 --- /dev/null +++ b/GutovVM/docs/data/lab_2_data/expmaze4.txt @@ -0,0 +1,50 @@ +S + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + E \ No newline at end of file diff --git a/GutovVM/docs/data/lab_2_data/expmaze5.txt b/GutovVM/docs/data/lab_2_data/expmaze5.txt new file mode 100644 index 0000000..2d08993 --- /dev/null +++ b/GutovVM/docs/data/lab_2_data/expmaze5.txt @@ -0,0 +1,51 @@ +################################################### +#S# # # # # +# # ##### # ######### # ##### # ################# # +# # # # # # # # # # +##### # ########### # ### # ############# ####### # +# # # # # # # # # +# ##### # ############# # # # ############# ##### # +# # # # # # # # # # # +# # ##### # ############# # # # ######### ##### # # +# # # # # # # # # # # # # +# # # ##### # ######### # # ##### ##### ##### # # # +# # # # # # # # # # # # # +# # ######### # ##### ########### # # # # ##### # # +# # # # # # # # # # # +# ############# ### # # ########### ##### # ##### # +# # # # # # # +############### # ### ########### ############### # +# # # # # # # +# ############# ### # # ##### # ######### # ##### # +# # # # # # # # # # # # # # +# # ############# ### # # # # # ####### # # # # # # +# # # # # # # # # # # # +# # ############### # ####### ####### # # ####### # +# # # # # # # # # # +# # # ############# ####### ####### # # ####### # # +# # # # # # # # # # # # +# # # # ######### ####### # # ##### # ####### # # # +# # # # # # # # # # # # # # +##### # # ##### ####### # ##### # # # # ### # ##### +# # # # # # # # # # # # # +# ##### ##### # # ############# # # # ### # ##### # +# # # # # # # # # # # # # +##### ##### # # # # ############# # ### # ##### # # +# # # # # # # # # # # # # +# # ##### # # # # ################### # ### # ### # +# # # # # # # # # # # # # # +# ##### # # # # # # ############### # ### # ### # # +# # # # # # # # # # # # # +##### # ######### ############### # ### # # ### # # +# # # # # # # # # +# ############# ##################### ####### # # # +# # # # # +############# ######################### ########### +# # # # +# ########### # ####################### # ####### # +# # # # # # # +########### # # # ####################### ####### # +# # # # ### # +# ########### ########################### #E# # +# ### # +################################################### diff --git a/GutovVM/docs/data/lab_2_data/graphics.py b/GutovVM/docs/data/lab_2_data/graphics.py new file mode 100644 index 0000000..e1bdc96 --- /dev/null +++ b/GutovVM/docs/data/lab_2_data/graphics.py @@ -0,0 +1,29 @@ +#Графики +import matplotlib.pyplot as plt +import pandas as pd + +df = pd.read_csv('results.csv', header=None, names=['lab','strategy','timeMs','cellsVisited','pathLength']) + +print(df) + +df_time = df.pivot(index='lab', columns='strategy', values=['timeMs','cellsVisited','pathLength']) + +print(df_time) + +# 1. График только для Времени +df_time["timeMs"].plot(kind="bar", figsize=(10, 5), rot=0) +plt.title("Время работы стратегий (мс)") +plt.ylabel("timeMs") +plt.show() + +# 2. График для Посещенных клеток +df_time["cellsVisited"].plot(kind="bar", figsize=(10, 5), rot=0) +plt.title("Количество посещенных клеток") +plt.ylabel("cellsVisited") +plt.show() + +# 3. График для Длины пути +df_time["pathLength"].plot(kind="bar", figsize=(10, 5), rot=0) +plt.title("Длина найденного пути") +plt.ylabel("pathLength") +plt.show() \ No newline at end of file diff --git a/GutovVM/docs/data/lab_2_data/main.py b/GutovVM/docs/data/lab_2_data/main.py new file mode 100644 index 0000000..4342cfc --- /dev/null +++ b/GutovVM/docs/data/lab_2_data/main.py @@ -0,0 +1,596 @@ +import numpy as np +import abc +from collections import deque +import heapq +import time +import os +import keyboard +import csv + +#Классы клетки и лабиринта + +class Cell: + + def __init__(self, coords, isWall = False, isStart = False, + isExit = False): + self.coords = coords + self.isWall = isWall + self.isStart = isStart + self.isExit = isExit + + def isPassable(self): + if self.isWall: + return False + return True + +class Maze: + + def __init__(self, cells, width, height, st, ex): + self.cells = cells + self.width = width + self.height = height + self.st = st + self.ex = ex + + def getCell(self,x,y): + try: + return self.cells[x][y] + except: + return None + + def getNeighbors(self,cell): + x,y = cell.coords + res = [] + for i,j in (x,y+1),(x,y-1),(x-1,y),(x+1,y): + cellij = self.getCell(i,j) + if i <= self.width-1 and j <= self.height-1 and 0 <= i and 0 <= j and cellij is not None: + if cellij.isPassable(): + res.append(cellij) + else: + res.append(None) + else: + res.append(None) + + return res + +#Тестирование классов клетки и лабиринта + +# cell1 = Cell((1,2), isExit = True, isWall = True, isStart = False) + +# print(cell1.isPassable()) +# print(cell1.isStart) +# print(cell1.coords) + +# width, height = 3,3 + +# cells = np.full((width,height), None, dtype=object) + +# for x in range(width): +# for y in range(height): +# if x != 0 and x != width-1 and y != 0 and y != height-1: +# cells[x][y] = Cell((x,y), isWall = False) +# else: +# cells[x][y] = Cell((x,y), isWall = True) + +# print(cells) + +# maze1 = Maze(cells, width, height, cells[0], cells[-1]) + +# for column in cells: +# for cell in column: +# print(cell.coords) +# print(maze1.getNeighbors(cell)) + +# print('\n') + +#Интерфейс постройки лабиринта + +class MazeBuilder(abc.ABC): + + @abc.abstractmethod + def buildFromFile(filename): pass + +#Наследуем от него класс постройки из текстового файла + +class TextFileMazeBuilder(MazeBuilder): + + def buildFromFile(filename): + with open(filename, "r") as file: + + rows = file.read().splitlines() + + #print(rows) + + width = 0 + height = 0 + for row in rows: + height += 1 + if len(row) > width: + width = len(row) + + #print(width, height) + + st = (0,0) + ex = (width,height) + + cells = np.full((width,height), None, dtype=object) + + flagst = False + flagex = False + for y in range(height): + for x in range(width): + isWall = False + isStart = False + isExit = False + + if rows[-(y+1)][x] == '#': + isWall = True + elif rows[-(y+1)][x] == 'S': + isStart = True + st = (x,y) + flagst = True + #print('Старт в',x,y) + elif rows[-(y+1)][x] == 'E': + isExit = True + ex = (x,y) + flagex = True + #print('Выход в',x,y) + elif rows[-(y+1)][x] != ' ': + raise ValueError("Неверный формат лабиринта! Пожалуйста, используйте только символы #,S,E и пробелы") + + cells[x][y] = Cell((x,y), isWall, isStart, isExit) + + if flagst and flagex: + + return Maze(cells, width, height, cells[st[0]][st[1]], cells[ex[0]][ex[1]]) + + raise ValueError('В лабаиринте должны быть вход и выход (S и E)') + + +# builder = TextFileMazeBuilder + +# maze = builder.buildFromFile('maze1.txt') + +# print(maze) + + +#Интерфейс поиска пути + +class PathFindingStrategy(abc.ABC): + + @abc.abstractmethod + def findPath(self, maze, st, ex): pass + +#Поиск в глубину + +class DFS(PathFindingStrategy): + + def findPath(self,maze,st,ex): + + stack = [st] + + self.visited = {st.coords} #по координатам надёжнее, а то вдруг адрес изменится + + pathmap = {} + + while stack: + cell = stack.pop() + + if cell.coords == ex.coords: + + #маршрут выстраивается в обратном порядке и разворачивается + path = [] + while cell.coords != st.coords: + path.append(cell) + cell = pathmap[cell.coords] + path.append(st) + path = path[::-1] + return path + + for n in maze.getNeighbors(cell): + if n != None and n.coords not in self.visited: + self.visited.add(n.coords) + pathmap[n.coords] = cell + stack.append(n) + + return None + +# path = DFS().findPath(maze,maze.st,maze.ex) + +# print('путь поиском в глубину:') +# for cell in path: +# print(cell.coords) + + +class BFS(PathFindingStrategy): + + def findPath(self,maze,st,ex): + + queue = deque([st]) + + self.visited = {st.coords} #по координатам надёжнее, а то вдруг адрес изменится + + pathmap = {} + + while queue: + cell = queue.popleft() + + if cell.coords == ex.coords: + + + path = [] + while cell.coords != st.coords: + path.append(cell) + cell = pathmap[cell.coords] + path.append(st) + path = path[::-1] + return path + + for n in maze.getNeighbors(cell): + if n != None and n.coords not in self.visited: + self.visited.add(n.coords) + pathmap[n.coords] = cell + queue.append(n) + + return None + +# path = BFS().findPath(maze,maze.st,maze.ex) + +# print('путь поиском в ширину:') +# for cell in path: +# print(cell.coords) + +class Astar(PathFindingStrategy): + + def findPath(self,maze,st,ex): + + c = 0 + hp_queue = [(0,c,st)] + + self.g_score = {st.coords: 0} + + pathmap = {} + + hp_queue_coords = {st.coords} #нам важна скорость + + while hp_queue: + + cell = heapq.heappop(hp_queue)[2] + hp_queue_coords.remove(cell.coords) + + if cell.coords == ex.coords: + + path = [] + while cell.coords != st.coords: + path.append(cell) + cell = pathmap[cell.coords] + path.append(st) + path = path[::-1] + self.visited = set(self.g_score.keys()) #экий костыль + return path + + for n in maze.getNeighbors(cell): + new_g_score = self.g_score[cell.coords] + 1 + + if n is not None and new_g_score < self.g_score.get(n.coords, float('inf')): + pathmap[n.coords] = cell + self.g_score[n.coords] = new_g_score + + h_score = abs(n.coords[0]-ex.coords[0]) + abs(n.coords[1]-ex.coords[1]) + + #f = g + h + #h - манхэттенское расстояние + full_score = new_g_score + h_score + + if n.coords not in hp_queue_coords: + c += 1 + heapq.heappush(hp_queue, (full_score, c, n)) + hp_queue_coords.add(n.coords) + + self.visited = set(self.g_score.keys()) #экий костыль 2: возвращение ситхов + return None + +# path = Astar().findPath(maze,maze.st,maze.ex) + +# print('путь с A*:') +# for cell in path: +# print(cell.coords) + +#Класс статистики поиска пути и класс оркестратор + +class SearchStats(): + + def __init__(self, timeMs, visitedCells, pathLength): + self.timeMs = timeMs + self.visitedCells = visitedCells + self.pathLength = pathLength + +class MazeSolver(): + + def __init__(self, maze, strategy): + self.maze = maze + self.strategy = strategy + self.observers = [ConsoleView(maze)] + + for observer in self.observers: + observer.update(MazeEvent('maze_loaded',maze,maze.st.coords)) + + def setStrategy(self,strategy): + self.strategy = strategy + + def solve(self): + + start = time.perf_counter() + path = self.strategy.findPath(self.maze,self.maze.st,self.maze.ex) + end = time.perf_counter() + + elapsed = end - start + + visitedCells = len(self.strategy.visited) + + if path is not None: + pathLength = len(path) + + for observer in self.observers: + observer.update(MazeEvent('path_found',self.maze,path[-1].coords,path)) + + else: + pathLength = 0 + for observer in self.observers: + observer.update(MazeEvent('path_found',self.maze,None,path)) + + return SearchStats(elapsed*1000, visitedCells, pathLength) + +# MS = MazeSolver(maze, DFS()) +# Stats = MS.solve() +# print(Stats.timeMs) +# print(Stats.visitedCells) +# print(Stats.pathLength) + +# MS = MazeSolver(maze, BFS()) +# Stats = MS.solve() +# print(Stats.timeMs) +# print(Stats.visitedCells) +# print(Stats.pathLength) + +# MS = MazeSolver(maze, Astar()) +# Stats = MS.solve() +# print(Stats.timeMs) +# print(Stats.visitedCells) +# print(Stats.pathLength) + + +#Класс для событий + +class MazeEvent(): + + def __init__(self,event_type, maze, player_position = None, path = []): + if player_position is None: + player_position = maze.st.coords + self.event_type = event_type + self.maze = maze + self.player_position = player_position + self.path = path + +#Интерфейс наблюдатель + +class Observer(abc.ABC): + + @abc.abstractmethod + def update(self, event): + + if not isinstance(event, (str, MazeEvent)): + raise TypeError('Только строки и объекты события') + + elif isinstance(event, MazeEvent) and event.event_type not in ('path_found','move','maze_loaded'): + raise TypeError('Только события "path_found","move","maze_loaded"') + +#Класс консольного просмотра + +class ConsoleView(Observer): + + def __init__(self, maze, player_position = (0,0), path = []): + + self.maze = maze + self.player_position = player_position + self.path = path + + def update(self, event): + + super().update(event) #проверка через сам интерфейс + + if isinstance(event, str): + print('') + print(event+'\n') + self.render(self.maze, self.player_position, self.path) + + else: + print('') + print(event.event_type+'\n') + if event.player_position is not None: + self.player_position = event.player_position + if event.path is not None and event.path: + self.path = event.path + self.render(event.maze, self.player_position, self.path) + + def render(self, maze, player_position, path): + + os.system('cls' if os.name == 'nt' else 'clear') + + #из-за системы координат надо всё опять транспонировать + + res = [] + for row in maze.cells.T[::-1]: + subres = [] + for cell in row: + if cell.isWall: + subres += '#' + elif cell.isStart: + subres += 'S' + elif cell.isExit: + subres += 'E' + else: + subres += ' ' + res.append(subres) + + for cell in path: + x,y = cell.coords + if res[-(y+1)][x] != 'S': + res[-(y+1)][x] = '*' + + res[-(player_position[1]+1)][player_position[0]] = 'X' + + for row in res: + print(''.join(row)) + +# builder = TextFileMazeBuilder + +# maze = builder.buildFromFile('maze1.txt') + +# print(maze) + +# CV = ConsoleView(maze, (0,0)) +# CV.update('Что-то случилось') + +# ME = MazeEvent('maze_loaded', maze, (0,0)) + +# CV.update(ME) + +# CV.update('Что-то случилось') + +#Интерфейс для команд + +class Command(abc.ABC): + + @abc.abstractmethod + def execute(self): pass + + @abc.abstractmethod + def undo(self): pass + +#Класс команды движения + +class MoveCommand(Command): + + def __init__(self): + self.previousCell = (0,0) + + def execute(self,player,direction): + + self.previousCell = player.currentCell + + resCell = (self.previousCell[0]+direction.dir[0],self.previousCell[1]+direction.dir[1]) + + player.moveTo(resCell) + + def undo(self,player): + + player.moveTo(self.previousCell) + +#Класс игрока + +class Player(): + + #Он хранит не текущую клетку, а только её координаты. Поскольку + #нам надо перемещать игрока динамически, а команда для перемещения + #не принимает лабиринт в качестве аргумента, следующую клетку мы + #как объект получить не можем, а можем получить только её координаты. + + def __init__(self, currentCell): + + self.currentCell = currentCell + + def moveTo(self, cell): + + self.currentCell = cell + +#Класс направление + +class Direction(): + + def __init__(self, x,y): + self.dir = (x,y) + +#Тест системы перемещения клавиатурой :D + +builder = TextFileMazeBuilder + +maze = builder.buildFromFile('maze1.txt') + +MS = MazeSolver(maze, DFS()) + +MS.solve() + +MC = MoveCommand() + +CV = MS.observers[0] + +player1 = Player(CV.player_position) + +instruct = '\nПеремещайтесь на W/A/S/D. Для отмены используйте ctrl+Z. Для выхода из режима перемещения команда X.\n' + +def move(player, direction): + + resCoords = (player.currentCell[0]+direction.dir[0], player.currentCell[1]+direction.dir[1]) + resCell = maze.getCell(resCoords[0], resCoords[1]) + if resCell == None or resCell.isWall: + return + MC.execute(player, direction) + CV.update(MazeEvent('move', maze, player.currentCell)) + print(instruct) + +def undo(player): + + MC.undo(player) + CV.update(MazeEvent('move', maze, player.currentCell)) + +print(instruct) + +keyboard.add_hotkey('w', move, args=[player1, Direction(0,1)]) + +keyboard.add_hotkey('s', move, args=[player1, Direction(0,-1)]) + +keyboard.add_hotkey('a', move, args=[player1, Direction(-1,0)]) + +keyboard.add_hotkey('d', move, args=[player1, Direction(1,0)]) + +keyboard.add_hotkey('ctrl+z', undo, args=[player1]) + +keyboard.wait('x') +keyboard.unhook_all() + + + +#Эксперимент + +res = [] + +strategyList = [BFS(),DFS(),Astar()] +sNamesList = ['BFS','DFS','Astar'] +labNamesList = ['10x10','50x50','100x100','empty','no exit'] +for strategy in range(3): + for i in range(1,6): + + subres1 = [] + subres2 = [] + subres3 = [] + + maze_name = 'expmaze' + str(i) + '.txt' + + maze = TextFileMazeBuilder.buildFromFile(maze_name) + + MS = MazeSolver(maze, strategyList[strategy]) + + for j in range(10): + Stats = MS.solve() + subres1.append(Stats.timeMs) + subres2.append(Stats.visitedCells) + subres3.append(Stats.pathLength) + + res.append([labNamesList[i-1],sNamesList[strategy],sum(subres1)/10., sum(subres2)/10., sum(subres3)/10.]) + +print(res) + +with open("results.csv", "w", newline="") as f: + writer = csv.writer(f) + writer.writerows(res) \ No newline at end of file diff --git a/GutovVM/docs/data/lab_2_data/maze1.txt b/GutovVM/docs/data/lab_2_data/maze1.txt new file mode 100644 index 0000000..a1d1619 --- /dev/null +++ b/GutovVM/docs/data/lab_2_data/maze1.txt @@ -0,0 +1,6 @@ +## ####S# ## +# ## # ## +## # # # # + # ### # +# ## ## E +# ##### ###### \ No newline at end of file diff --git a/GutovVM/docs/data/lab_2_data/mermaid diagram.txt b/GutovVM/docs/data/lab_2_data/mermaid diagram.txt new file mode 100644 index 0000000..eeab4a8 --- /dev/null +++ b/GutovVM/docs/data/lab_2_data/mermaid diagram.txt @@ -0,0 +1,128 @@ +classDiagram + + class Cell{ + +tuple coords + +bool isWall + +bool isStart + +bool isExit + +isPassable(): bool + } + + class Maze{ + +np.array cells + +int width + +int height + +Cell st + +Cell ex + +getCell(x,y): Cell + +getNeighbors(cell): List~Cell~ + } + + class MazeBuilder{ + <> + +buildFromFile(filename): Maze + } + + class TextFileMazeBuilder{ + +buildFromFile(filename): Maze + } + + MazeBuilder <|.. TextFileMazeBuilder + + class PathFindingStrategy{ + <> + +findPath(maze,st,ex): list~Cell~ + } + + class BFS{ + +set~tuple~ visited + +findPath(maze,st,ex): list~Cell~ + } + + class DFS{ + +set~tuple~ visited + +findPath(maze,st,ex): list~Cell~ + } + + class Astar{ + +dict~tuple, int~ + +set~tuple~ visited + +findPath(maze,st,ex): list~Cell~ + } + + PathFindingStrategy <|.. BFS + PathFindingStrategy <|.. DFS + PathFindingStrategy <|.. Astar + + class SearchStats{ + +float timeMs + +int visitedCells + +int pathLength + } + + class MazeSolver{ + +Maze maze + +PathFindingStrategy strategy + +list~ConsoleView~ observers + +setStrategy(strategy) + +solve(): SearchStats + } + + class MazeEvent{ + +string event_type + +Maze maze + +tuple player_position + +list~tuple~ path + } + + class Observer{ + <> + +update(event) + } + + class ConsoleView{ + +Maze maze + +tuple player_position + +list~tuple~ path + +update(event) + +render(maze,player_position,path) + } + + class Command{ + <> + +execute() + +undo() + } + + class MoveCommand{ + +tuple previousCell + +execute(player,direction) + +undo(player) + } + + Command <|.. MoveCommand + + class Player{ + +tuple currentCell + +moveTo(cell) + } + + class Direction{ + +tuple dir + } + + MazeSolver --> PathFindingStrategy: uses + MazeBuilder --> Maze: creates + Maze --> Cell: contains + ConsoleView ..|> Observer + MazeSolver --> Observer: notifies + MazeSolver --> MazeEvent: creates + Observer --> MazeEvent: accepts + MoveCommand --> Player: moves + MoveCommand --> Direction: uses + ConsoleView --> Player: accepts position + ConsoleView --> Maze: renders + MazeSolver --> SearchStats: returns + MazeSolver --> Maze: accepts + MazeEvent --> Player: stores position + Player --> Cell: saves coords \ No newline at end of file diff --git a/GutovVM/docs/data/lab_2_data/mermaid-diagram-2026-05-28-010725.png b/GutovVM/docs/data/lab_2_data/mermaid-diagram-2026-05-28-010725.png new file mode 100644 index 0000000..3472f4a Binary files /dev/null and b/GutovVM/docs/data/lab_2_data/mermaid-diagram-2026-05-28-010725.png differ diff --git a/GutovVM/docs/data/lab_2_data/mermaid-diagram-2026-05-28-010727.svg b/GutovVM/docs/data/lab_2_data/mermaid-diagram-2026-05-28-010727.svg new file mode 100644 index 0000000..c7a9b2e --- /dev/null +++ b/GutovVM/docs/data/lab_2_data/mermaid-diagram-2026-05-28-010727.svg @@ -0,0 +1,3 @@ + + +

uses

creates

contains

notifies

creates

accepts

moves

uses

accepts position

renders

returns

accepts

stores position

saves coords

Cell

+tuple coords

+bool isWall

+bool isStart

+bool isExit

+isPassable() : : bool

Maze

+np.array cells

+int width

+int height

+Cell st

+Cell ex

+getCell(x,y) : : Cell

+getNeighbors(cell) : : List<Cell>

«interface»

MazeBuilder

+buildFromFile(filename) : : Maze

TextFileMazeBuilder

+buildFromFile(filename) : : Maze

«interface»

PathFindingStrategy

+findPath(maze,st,ex) : : list<Cell>

BFS

+set<tuple> visited

+findPath(maze,st,ex) : : list<Cell>

DFS

+set<tuple> visited

+findPath(maze,st,ex) : : list<Cell>

Astar

+dict<tuple, int>

+set<tuple> visited

+findPath(maze,st,ex) : : list<Cell>

SearchStats

+float timeMs

+int visitedCells

+int pathLength

MazeSolver

+Maze maze

+PathFindingStrategy strategy

+list<ConsoleView> observers

+setStrategy(strategy)

+solve() : : SearchStats

MazeEvent

+string event_type

+Maze maze

+tuple player_position

+list<tuple> path

«interface»

Observer

+update(event)

ConsoleView

+Maze maze

+tuple player_position

+list<tuple> path

+update(event)

+render(maze,player_position,path)

«interface»

Command

+execute()

+undo()

MoveCommand

+tuple previousCell

+execute(player,direction)

+undo(player)

Player

+tuple currentCell

+moveTo(cell)

Direction

+tuple dir

\ No newline at end of file diff --git a/GutovVM/docs/data/lab_2_data/results copy 28 05 26.csv b/GutovVM/docs/data/lab_2_data/results copy 28 05 26.csv new file mode 100644 index 0000000..af0d4ff --- /dev/null +++ b/GutovVM/docs/data/lab_2_data/results copy 28 05 26.csv @@ -0,0 +1,16 @@ +;;_;_ ();_ () +10x10;BFS;0.08966999594122171;36;21 +50x50;BFS;2.187670022249222;1020;501 +100x100;BFS;8.31503001973033;4172;414 +empty;BFS;5.047210049815476;2500;99 +no exit;BFS;2.197379991412163;1072;0 +10x10;DFS;0.09059999138116837;37;21 +50x50;DFS;1.264189975336194;593;581 +100x100;DFS;5.151620041579008;2384;1122 +empty;DFS;3.3813500544056296;2500;1275 +no exit;DFS;2.2671299753710628;1072;0 +10x10;Astar;0.11618996504694223;33;21 +50x50;Astar;2.8455600142478943;973;501 +100x100;Astar;9.197140019387007;2980;414 +empty;Astar;7.771430024877191;2500;99 +no exit;Astar;3.192879958078265;1072;0 diff --git a/GutovVM/docs/data/lab_2_data/results.csv b/GutovVM/docs/data/lab_2_data/results.csv new file mode 100644 index 0000000..4ffbee5 --- /dev/null +++ b/GutovVM/docs/data/lab_2_data/results.csv @@ -0,0 +1,15 @@ +10x10,BFS,0.08966999594122171,36.0,21.0 +50x50,BFS,2.187670022249222,1020.0,501.0 +100x100,BFS,8.31503001973033,4172.0,414.0 +empty,BFS,5.047210049815476,2500.0,99.0 +no exit,BFS,2.197379991412163,1072.0,0.0 +10x10,DFS,0.09059999138116837,37.0,21.0 +50x50,DFS,1.264189975336194,593.0,581.0 +100x100,DFS,5.151620041579008,2384.0,1122.0 +empty,DFS,3.3813500544056296,2500.0,1275.0 +no exit,DFS,2.2671299753710628,1072.0,0.0 +10x10,Astar,0.11618996504694223,33.0,21.0 +50x50,Astar,2.8455600142478943,973.0,501.0 +100x100,Astar,9.197140019387007,2980.0,414.0 +empty,Astar,7.771430024877191,2500.0,99.0 +no exit,Astar,3.192879958078265,1072.0,0.0 diff --git a/GutovVM/docs/otchet1.docx b/GutovVM/docs/otchet1.docx new file mode 100644 index 0000000..d5ff995 Binary files /dev/null and b/GutovVM/docs/otchet1.docx differ diff --git a/GutovVM/docs/otchet1.pdf b/GutovVM/docs/otchet1.pdf new file mode 100644 index 0000000..96a655f Binary files /dev/null and b/GutovVM/docs/otchet1.pdf differ diff --git a/GutovVM/docs/otchet2.docx b/GutovVM/docs/otchet2.docx new file mode 100644 index 0000000..850694a Binary files /dev/null and b/GutovVM/docs/otchet2.docx differ diff --git a/GutovVM/docs/otchet2.pdf b/GutovVM/docs/otchet2.pdf new file mode 100644 index 0000000..6476f1a Binary files /dev/null and b/GutovVM/docs/otchet2.pdf differ diff --git a/GutovVM/docs/~$tchet1.docx b/GutovVM/docs/~$tchet1.docx new file mode 100644 index 0000000..7ee9492 Binary files /dev/null and b/GutovVM/docs/~$tchet1.docx differ diff --git a/GutovVM/docs/~$tchet2.docx b/GutovVM/docs/~$tchet2.docx new file mode 100644 index 0000000..53bfe89 Binary files /dev/null and b/GutovVM/docs/~$tchet2.docx differ diff --git a/GutovVM/docs/~WRL0005.tmp b/GutovVM/docs/~WRL0005.tmp new file mode 100644 index 0000000..3ce130a Binary files /dev/null and b/GutovVM/docs/~WRL0005.tmp differ