Merge pull request '[2] lab_2 and lab_1 finished and merged' (#197) from gutovvm/2026-rff_mp:GutovVM into develop

Reviewed-on: #197
This commit is contained in:
kit8nino 2026-05-30 11:35:37 +00:00
commit 0539c6b573
25 changed files with 1810 additions and 0 deletions

View File

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

View File

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

View File

@ -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']]

View File

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

View File

@ -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
1 Linked list shuffled Insert 2.9601924599846825
2 Linked list shuffled Find 0.02592504001222551
3 Linked list shuffled Delete 0.01210075996350497
4 Hash-table shuffled Insert 0.004802840016782284
5 Hash-table shuffled Find 3.839998971670866e-05
6 Hash-table shuffled Delete 2.0040012896060943e-05
7 BST shuffled Insert 0.0542771200183779
8 BST shuffled Find 0.0003209599992260337
9 BST shuffled Delete 0.00015207994729280472
10 Linked list sorted Insert 2.5840181399835274
11 Linked list sorted Find 0.021389540005475282
12 Linked list sorted Delete 0.010239119990728796
13 Hash-table sorted Insert 0.004485400021076202
14 Hash-table sorted Find 3.3660023473203185e-05
15 Hash-table sorted Delete 1.8039997667074203e-05
16 BST sorted Insert 0.03127337999176234
17 BST sorted Find 0.00029561996925622227
18 BST sorted Delete 0.00014696004800498485

View File

@ -0,0 +1,10 @@
##########
#S# #
# # #### #
# # # #
### # ## #
# # #
# ##### ##
# # #
##### ##E#
##########

View File

@ -0,0 +1,51 @@
###################################################
#S# # # # #
# # ##### # ######### # ##### # ################# #
# # # # # # # # # #
##### # ########### # ### # ############# ####### #
# # # # # # # # #
# ##### # ############# # # # ############# ##### #
# # # # # # # # # # #
# # ##### # ############# # # # ######### ##### # #
# # # # # # # # # # # # #
# # # ##### # ######### # # ##### ##### ##### # # #
# # # # # # # # # # # # #
# # ######### # ##### ########### # # # # ##### # #
# # # # # # # # # # #
# ############# ### # # ########### ##### # ##### #
# # # # # # #
############### # ### ########### ############### #
# # # # # # #
# ############# ### # # ##### # ######### # ##### #
# # # # # # # # # # # # # #
# # ############# ### # # # # # ####### # # # # # #
# # # # # # # # # # # #
# # ############### # ####### ####### # # ####### #
# # # # # # # # # #
# # # ############# ####### ####### # # ####### # #
# # # # # # # # # # # #
# # # # ######### ####### # # ##### # ####### # # #
# # # # # # # # # # # # # #
##### # # ##### ####### # ##### # # # # ### # #####
# # # # # # # # # # # # #
# ##### ##### # # ############# # # # ### # ##### #
# # # # # # # # # # # # #
##### ##### # # # # ############# # ### # ##### # #
# # # # # # # # # # # # #
# # ##### # # # # ################### # ### # ### #
# # # # # # # # # # # # # #
# ##### # # # # # # ############### # ### # ### # #
# # # # # # # # # # # # #
##### # ######### ############### # ### # # ### # #
# # # # # # # # #
# ############# ##################### ####### # # #
# # # # #
############# ######################### ###########
# # # #
# ########### # ####################### # ####### #
# # # # # # #
########### # # # ####################### ####### #
# # # # #
# ########### ################################### #
# E#
###################################################

View File

@ -0,0 +1,97 @@
#####################################################################################################
#S# # # # # #
# # ##### # ################# # ######### # ################# # ################################### #
# # # # # # # # # # # # # #
##### # ############# ####### # # ##### # # # ############# # # # ################################# #
# # # # # # # # # # # # # # # # #
# ##### # ############# ####### # # # # # # # # ############# # # # ############################### #
# # # # # # # # # # # # # # # # # #
# # ##### # ######### ########### # # # # # # ############### # # # # ############################# #
# # # # # # # # # # # # # # # #
# # # ##### # ##### ############### ##### ################# # # # # # ############################# #
# # # # # # # # # # #
# # ############# ######################### ############### # ##### # ############################# #
# # # # # # # # #
# ############### # ####################### # ############# # # ##### # ########################### #
# # # # # # # # # # # #
############### # # # ##################### # # ############# # # ##### # ######################### #
# # # # # # # # # # # # # #
# ############# # # # # ################### # # # ############# # # ##### # ####################### #
# # # # # # # # # # # # # # # # #
# # ############# # # # # ################# # # # # ############# # ##### # # ##################### #
# # # # # # # # # # # # # # # # # #
# # # ############# # # # # ############### # # # ############### # ##### # # # ################### #
# # # # # # # # # # # # # # # #
# # # # ############# ##################### # # ######################### # # # # ################# #
# # # # # # # # # # # # #
# # # # # ################################# # ########################### # # # # # ############### #
# # # # # # # # # # #
# # # ####### ############################### ############################# ####### ############### #
# # # # # # # #
# # ######### # ############################# # ########################### ####### # ############# #
# # # # # # # # # #
# ########### # # ########################### # # ######################### ####### # ############# #
# # # # # # # # # #
############# # # # ######################### # ########################### # ##### # ############# #
# # # # # # # # # # #
# ########### # # # # ####################### ############################# # # ##### # #############
# # # # # # # # # # # # #
# # ######### # # # # # ##################### # ########################### # # # ##### ########### #
# # # # # # # # # # # # # # # # #
# # # ####### # # # # # # ################### # # ######################### # # # # ##### ######### #
# # # # # # # # # # # # # # # # # # #
# # # # ##### # ##### # # # ################# # ########################### # # # # # ##### ####### #
# # # # # # # # # # # # # # # # # # #
# ##### # # # # # ##### # # # ############### ############################# ####### # # ##### ##### #
# # # # # # # # # # # # # # # # # # #
# # ##### # # # # # ##### # # # ############################################# ####### # # # # # ### #
# # # # # # # # # # # # # # # #
# ######### ####### ########### # ############################################# ####### ### # ### # #
# # # # # # # # # # #
########### # ####### ########### # ########################################### ######### # ### # # #
# # # # # # # # # # # #
# ########### # ##### # ########### # ######################################### # ######### ### # # #
# # # # # # # # # # # # # # # #
# # ######### # # # # # # ######### # ######################################### # # ##### ### # # # #
# # # # # # # # # # # # # # # # # # # # #
# # # ####### # # # # # # # ####### # ######################################### # # # # ### # # # # #
# # # # # # # # # # # # # # # # # # #
# ##### ####### ######### # # ##### ########################################### # # # ### # ### # # #
# # # # # # # # # # # # # # #
####### # ############### # # ##### # ######################################### # # ### # ### # # # #
# # # # # # # # # # # # # # # #
# ####### # ############# # ### # ### # ######################################### ### # ### # ### # #
# # # # # # # # # # # # # # # # #
# # ##### # ############### ### # # ### # ######################################### # # ### # ### # #
# # # # # # # # # # # # # # # # #
# # # # ##### ############### # # ##### # # ####################################### # # ### # ### # #
# # # # # # # # # # # # # # # # #
# # # ######### ############# # # # ##### # # ##################################### ##### # ### # # #
# # # # # # # # # # # # # # #
# # ############# ############### # # ##### # # ################################### # ##### ### # # #
# # # # # # # # # # # # # #
# ############### # ############# # # # ##### # # ################################# # # ##### ##### #
# # # # # # # # # # # # # # #
# ################# # ########### # # # # ##### # # ############################### # # # ##### ### #
# # # # # # # # # # # # # # # # #
# # ############### # # ######### # ##### # ##### # # ############################# # # # # ##### # #
# # # # # # # # # # # # # # # # # #
# # # ############# # # # ####### ######### # ##### # # ########################### ####### # ##### #
# # # # # # # # # # # # # # # # # #
# # # # ############# # # # ##### # ####### # # ##### # # ######################### # ####### # #####
# # # # # # # # # # # # # # # # # # # # # # #
# # # # # ########### # # # # # # # # ##### # # # ##### # # ####################### # # ##### # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # ##### # ######### # ##### # # # # # # # # # # # ##### # # ##################### # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # #
# ######### # ######### ############### ######### # ##### # # ##################### ##### # ##### # #
# # # # # # # # # # # # # # # #
########### # ######### # ##################### # # # ##### # # ################### # ##### # # # # #
# # # # # # # # # # # # # # # # # #
# ####################### # ################### # # # # ##### # # ################# # # ##### # # # #
# # # # # # # # # # # # # # # # #
# # ##################### # # ################# ##### # # ##### # # ############### # # # ##### ### #
# # # # # # # # # # # # # # # # # # #
# # # ################### # # # ############### # ##### # # ##### # # ############# # # # # ##### # #
# # # # # # # # # # # # # # # # E
#####################################################################################################

View File

@ -0,0 +1,50 @@
S
E

View File

@ -0,0 +1,51 @@
###################################################
#S# # # # #
# # ##### # ######### # ##### # ################# #
# # # # # # # # # #
##### # ########### # ### # ############# ####### #
# # # # # # # # #
# ##### # ############# # # # ############# ##### #
# # # # # # # # # # #
# # ##### # ############# # # # ######### ##### # #
# # # # # # # # # # # # #
# # # ##### # ######### # # ##### ##### ##### # # #
# # # # # # # # # # # # #
# # ######### # ##### ########### # # # # ##### # #
# # # # # # # # # # #
# ############# ### # # ########### ##### # ##### #
# # # # # # #
############### # ### ########### ############### #
# # # # # # #
# ############# ### # # ##### # ######### # ##### #
# # # # # # # # # # # # # #
# # ############# ### # # # # # ####### # # # # # #
# # # # # # # # # # # #
# # ############### # ####### ####### # # ####### #
# # # # # # # # # #
# # # ############# ####### ####### # # ####### # #
# # # # # # # # # # # #
# # # # ######### ####### # # ##### # ####### # # #
# # # # # # # # # # # # # #
##### # # ##### ####### # ##### # # # # ### # #####
# # # # # # # # # # # # #
# ##### ##### # # ############# # # # ### # ##### #
# # # # # # # # # # # # #
##### ##### # # # # ############# # ### # ##### # #
# # # # # # # # # # # # #
# # ##### # # # # ################### # ### # ### #
# # # # # # # # # # # # # #
# ##### # # # # # # ############### # ### # ### # #
# # # # # # # # # # # # #
##### # ######### ############### # ### # # ### # #
# # # # # # # # #
# ############# ##################### ####### # # #
# # # # #
############# ######################### ###########
# # # #
# ########### # ####################### # ####### #
# # # # # # #
########### # # # ####################### ####### #
# # # # ### #
# ########### ########################### #E# #
# ### #
###################################################

View File

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

View File

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

View File

@ -0,0 +1,6 @@
## ####S# ##
# ## # ##
## # # # #
# ### #
# ## ## E
# ##### ######

View File

@ -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{
<<interface>>
+buildFromFile(filename): Maze
}
class TextFileMazeBuilder{
+buildFromFile(filename): Maze
}
MazeBuilder <|.. TextFileMazeBuilder
class PathFindingStrategy{
<<interface>>
+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{
<<interface>>
+update(event)
}
class ConsoleView{
+Maze maze
+tuple player_position
+list~tuple~ path
+update(event)
+render(maze,player_position,path)
}
class Command{
<<interface>>
+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

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 92 KiB

View File

@ -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
1 ëàáèðèíò ñòðàòåãèÿ âðåìÿ_ìñ ïîñåùåíî_êëåòîê (ñð) äëèíà_ïóòè (ñð)
2 10x10 BFS 0.08966999594122171 36 21
3 50x50 BFS 2.187670022249222 1020 501
4 100x100 BFS 8.31503001973033 4172 414
5 empty BFS 5.047210049815476 2500 99
6 no exit BFS 2.197379991412163 1072 0
7 10x10 DFS 0.09059999138116837 37 21
8 50x50 DFS 1.264189975336194 593 581
9 100x100 DFS 5.151620041579008 2384 1122
10 empty DFS 3.3813500544056296 2500 1275
11 no exit DFS 2.2671299753710628 1072 0
12 10x10 Astar 0.11618996504694223 33 21
13 50x50 Astar 2.8455600142478943 973 501
14 100x100 Astar 9.197140019387007 2980 414
15 empty Astar 7.771430024877191 2500 99
16 no exit Astar 3.192879958078265 1072 0

View File

@ -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
1 10x10 BFS 0.08966999594122171 36.0 21.0
2 50x50 BFS 2.187670022249222 1020.0 501.0
3 100x100 BFS 8.31503001973033 4172.0 414.0
4 empty BFS 5.047210049815476 2500.0 99.0
5 no exit BFS 2.197379991412163 1072.0 0.0
6 10x10 DFS 0.09059999138116837 37.0 21.0
7 50x50 DFS 1.264189975336194 593.0 581.0
8 100x100 DFS 5.151620041579008 2384.0 1122.0
9 empty DFS 3.3813500544056296 2500.0 1275.0
10 no exit DFS 2.2671299753710628 1072.0 0.0
11 10x10 Astar 0.11618996504694223 33.0 21.0
12 50x50 Astar 2.8455600142478943 973.0 501.0
13 100x100 Astar 9.197140019387007 2980.0 414.0
14 empty Astar 7.771430024877191 2500.0 99.0
15 no exit Astar 3.192879958078265 1072.0 0.0

BIN
GutovVM/docs/otchet1.docx Normal file

Binary file not shown.

BIN
GutovVM/docs/otchet1.pdf Normal file

Binary file not shown.

BIN
GutovVM/docs/otchet2.docx Normal file

Binary file not shown.

BIN
GutovVM/docs/otchet2.pdf Normal file

Binary file not shown.

BIN
GutovVM/docs/~$tchet1.docx Normal file

Binary file not shown.

BIN
GutovVM/docs/~$tchet2.docx Normal file

Binary file not shown.

BIN
GutovVM/docs/~WRL0005.tmp Normal file

Binary file not shown.