forked from UNN/2026-rff_mp
Compare commits
No commits in common. "lab_2" and "develop" have entirely different histories.
|
|
@ -1,57 +0,0 @@
|
||||||
#Графики
|
|
||||||
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()
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
#Графики через 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()
|
|
||||||
|
|
@ -1,176 +0,0 @@
|
||||||
Данный файл был создан в ручную копированием данных выводимых программой 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']]
|
|
||||||
|
|
@ -1,449 +0,0 @@
|
||||||
#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)
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
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,10 +0,0 @@
|
||||||
##########
|
|
||||||
#S# #
|
|
||||||
# # #### #
|
|
||||||
# # # #
|
|
||||||
### # ## #
|
|
||||||
# # #
|
|
||||||
# ##### ##
|
|
||||||
# # #
|
|
||||||
##### ##E#
|
|
||||||
##########
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
###################################################
|
|
||||||
#S# # # # #
|
|
||||||
# # ##### # ######### # ##### # ################# #
|
|
||||||
# # # # # # # # # #
|
|
||||||
##### # ########### # ### # ############# ####### #
|
|
||||||
# # # # # # # # #
|
|
||||||
# ##### # ############# # # # ############# ##### #
|
|
||||||
# # # # # # # # # # #
|
|
||||||
# # ##### # ############# # # # ######### ##### # #
|
|
||||||
# # # # # # # # # # # # #
|
|
||||||
# # # ##### # ######### # # ##### ##### ##### # # #
|
|
||||||
# # # # # # # # # # # # #
|
|
||||||
# # ######### # ##### ########### # # # # ##### # #
|
|
||||||
# # # # # # # # # # #
|
|
||||||
# ############# ### # # ########### ##### # ##### #
|
|
||||||
# # # # # # #
|
|
||||||
############### # ### ########### ############### #
|
|
||||||
# # # # # # #
|
|
||||||
# ############# ### # # ##### # ######### # ##### #
|
|
||||||
# # # # # # # # # # # # # #
|
|
||||||
# # ############# ### # # # # # ####### # # # # # #
|
|
||||||
# # # # # # # # # # # #
|
|
||||||
# # ############### # ####### ####### # # ####### #
|
|
||||||
# # # # # # # # # #
|
|
||||||
# # # ############# ####### ####### # # ####### # #
|
|
||||||
# # # # # # # # # # # #
|
|
||||||
# # # # ######### ####### # # ##### # ####### # # #
|
|
||||||
# # # # # # # # # # # # # #
|
|
||||||
##### # # ##### ####### # ##### # # # # ### # #####
|
|
||||||
# # # # # # # # # # # # #
|
|
||||||
# ##### ##### # # ############# # # # ### # ##### #
|
|
||||||
# # # # # # # # # # # # #
|
|
||||||
##### ##### # # # # ############# # ### # ##### # #
|
|
||||||
# # # # # # # # # # # # #
|
|
||||||
# # ##### # # # # ################### # ### # ### #
|
|
||||||
# # # # # # # # # # # # # #
|
|
||||||
# ##### # # # # # # ############### # ### # ### # #
|
|
||||||
# # # # # # # # # # # # #
|
|
||||||
##### # ######### ############### # ### # # ### # #
|
|
||||||
# # # # # # # # #
|
|
||||||
# ############# ##################### ####### # # #
|
|
||||||
# # # # #
|
|
||||||
############# ######################### ###########
|
|
||||||
# # # #
|
|
||||||
# ########### # ####################### # ####### #
|
|
||||||
# # # # # # #
|
|
||||||
########### # # # ####################### ####### #
|
|
||||||
# # # # #
|
|
||||||
# ########### ################################### #
|
|
||||||
# E#
|
|
||||||
###################################################
|
|
||||||
|
|
@ -1,97 +0,0 @@
|
||||||
#####################################################################################################
|
|
||||||
#S# # # # # #
|
|
||||||
# # ##### # ################# # ######### # ################# # ################################### #
|
|
||||||
# # # # # # # # # # # # # #
|
|
||||||
##### # ############# ####### # # ##### # # # ############# # # # ################################# #
|
|
||||||
# # # # # # # # # # # # # # # # #
|
|
||||||
# ##### # ############# ####### # # # # # # # # ############# # # # ############################### #
|
|
||||||
# # # # # # # # # # # # # # # # # #
|
|
||||||
# # ##### # ######### ########### # # # # # # ############### # # # # ############################# #
|
|
||||||
# # # # # # # # # # # # # # # #
|
|
||||||
# # # ##### # ##### ############### ##### ################# # # # # # ############################# #
|
|
||||||
# # # # # # # # # # #
|
|
||||||
# # ############# ######################### ############### # ##### # ############################# #
|
|
||||||
# # # # # # # # #
|
|
||||||
# ############### # ####################### # ############# # # ##### # ########################### #
|
|
||||||
# # # # # # # # # # # #
|
|
||||||
############### # # # ##################### # # ############# # # ##### # ######################### #
|
|
||||||
# # # # # # # # # # # # # #
|
|
||||||
# ############# # # # # ################### # # # ############# # # ##### # ####################### #
|
|
||||||
# # # # # # # # # # # # # # # # #
|
|
||||||
# # ############# # # # # ################# # # # # ############# # ##### # # ##################### #
|
|
||||||
# # # # # # # # # # # # # # # # # #
|
|
||||||
# # # ############# # # # # ############### # # # ############### # ##### # # # ################### #
|
|
||||||
# # # # # # # # # # # # # # # #
|
|
||||||
# # # # ############# ##################### # # ######################### # # # # ################# #
|
|
||||||
# # # # # # # # # # # # #
|
|
||||||
# # # # # ################################# # ########################### # # # # # ############### #
|
|
||||||
# # # # # # # # # # #
|
|
||||||
# # # ####### ############################### ############################# ####### ############### #
|
|
||||||
# # # # # # # #
|
|
||||||
# # ######### # ############################# # ########################### ####### # ############# #
|
|
||||||
# # # # # # # # # #
|
|
||||||
# ########### # # ########################### # # ######################### ####### # ############# #
|
|
||||||
# # # # # # # # # #
|
|
||||||
############# # # # ######################### # ########################### # ##### # ############# #
|
|
||||||
# # # # # # # # # # #
|
|
||||||
# ########### # # # # ####################### ############################# # # ##### # #############
|
|
||||||
# # # # # # # # # # # # #
|
|
||||||
# # ######### # # # # # ##################### # ########################### # # # ##### ########### #
|
|
||||||
# # # # # # # # # # # # # # # # #
|
|
||||||
# # # ####### # # # # # # ################### # # ######################### # # # # ##### ######### #
|
|
||||||
# # # # # # # # # # # # # # # # # # #
|
|
||||||
# # # # ##### # ##### # # # ################# # ########################### # # # # # ##### ####### #
|
|
||||||
# # # # # # # # # # # # # # # # # # #
|
|
||||||
# ##### # # # # # ##### # # # ############### ############################# ####### # # ##### ##### #
|
|
||||||
# # # # # # # # # # # # # # # # # # #
|
|
||||||
# # ##### # # # # # ##### # # # ############################################# ####### # # # # # ### #
|
|
||||||
# # # # # # # # # # # # # # # #
|
|
||||||
# ######### ####### ########### # ############################################# ####### ### # ### # #
|
|
||||||
# # # # # # # # # # #
|
|
||||||
########### # ####### ########### # ########################################### ######### # ### # # #
|
|
||||||
# # # # # # # # # # # #
|
|
||||||
# ########### # ##### # ########### # ######################################### # ######### ### # # #
|
|
||||||
# # # # # # # # # # # # # # # #
|
|
||||||
# # ######### # # # # # # ######### # ######################################### # # ##### ### # # # #
|
|
||||||
# # # # # # # # # # # # # # # # # # # # #
|
|
||||||
# # # ####### # # # # # # # ####### # ######################################### # # # # ### # # # # #
|
|
||||||
# # # # # # # # # # # # # # # # # # #
|
|
||||||
# ##### ####### ######### # # ##### ########################################### # # # ### # ### # # #
|
|
||||||
# # # # # # # # # # # # # # #
|
|
||||||
####### # ############### # # ##### # ######################################### # # ### # ### # # # #
|
|
||||||
# # # # # # # # # # # # # # # #
|
|
||||||
# ####### # ############# # ### # ### # ######################################### ### # ### # ### # #
|
|
||||||
# # # # # # # # # # # # # # # # #
|
|
||||||
# # ##### # ############### ### # # ### # ######################################### # # ### # ### # #
|
|
||||||
# # # # # # # # # # # # # # # # #
|
|
||||||
# # # # ##### ############### # # ##### # # ####################################### # # ### # ### # #
|
|
||||||
# # # # # # # # # # # # # # # # #
|
|
||||||
# # # ######### ############# # # # ##### # # ##################################### ##### # ### # # #
|
|
||||||
# # # # # # # # # # # # # # #
|
|
||||||
# # ############# ############### # # ##### # # ################################### # ##### ### # # #
|
|
||||||
# # # # # # # # # # # # # #
|
|
||||||
# ############### # ############# # # # ##### # # ################################# # # ##### ##### #
|
|
||||||
# # # # # # # # # # # # # # #
|
|
||||||
# ################# # ########### # # # # ##### # # ############################### # # # ##### ### #
|
|
||||||
# # # # # # # # # # # # # # # # #
|
|
||||||
# # ############### # # ######### # ##### # ##### # # ############################# # # # # ##### # #
|
|
||||||
# # # # # # # # # # # # # # # # # #
|
|
||||||
# # # ############# # # # ####### ######### # ##### # # ########################### ####### # ##### #
|
|
||||||
# # # # # # # # # # # # # # # # # #
|
|
||||||
# # # # ############# # # # ##### # ####### # # ##### # # ######################### # ####### # #####
|
|
||||||
# # # # # # # # # # # # # # # # # # # # # # #
|
|
||||||
# # # # # ########### # # # # # # # # ##### # # # ##### # # ####################### # # ##### # # # #
|
|
||||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
||||||
# # ##### # ######### # ##### # # # # # # # # # # # ##### # # ##################### # # # # # # # # #
|
|
||||||
# # # # # # # # # # # # # # # # # # # # #
|
|
||||||
# ######### # ######### ############### ######### # ##### # # ##################### ##### # ##### # #
|
|
||||||
# # # # # # # # # # # # # # # #
|
|
||||||
########### # ######### # ##################### # # # ##### # # ################### # ##### # # # # #
|
|
||||||
# # # # # # # # # # # # # # # # # #
|
|
||||||
# ####################### # ################### # # # # ##### # # ################# # # ##### # # # #
|
|
||||||
# # # # # # # # # # # # # # # # #
|
|
||||||
# # ##################### # # ################# ##### # # ##### # # ############### # # # ##### ### #
|
|
||||||
# # # # # # # # # # # # # # # # # # #
|
|
||||||
# # # ################### # # # ############### # ##### # # ##### # # ############# # # # # ##### # #
|
|
||||||
# # # # # # # # # # # # # # # # E
|
|
||||||
#####################################################################################################
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
S
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
E
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
###################################################
|
|
||||||
#S# # # # #
|
|
||||||
# # ##### # ######### # ##### # ################# #
|
|
||||||
# # # # # # # # # #
|
|
||||||
##### # ########### # ### # ############# ####### #
|
|
||||||
# # # # # # # # #
|
|
||||||
# ##### # ############# # # # ############# ##### #
|
|
||||||
# # # # # # # # # # #
|
|
||||||
# # ##### # ############# # # # ######### ##### # #
|
|
||||||
# # # # # # # # # # # # #
|
|
||||||
# # # ##### # ######### # # ##### ##### ##### # # #
|
|
||||||
# # # # # # # # # # # # #
|
|
||||||
# # ######### # ##### ########### # # # # ##### # #
|
|
||||||
# # # # # # # # # # #
|
|
||||||
# ############# ### # # ########### ##### # ##### #
|
|
||||||
# # # # # # #
|
|
||||||
############### # ### ########### ############### #
|
|
||||||
# # # # # # #
|
|
||||||
# ############# ### # # ##### # ######### # ##### #
|
|
||||||
# # # # # # # # # # # # # #
|
|
||||||
# # ############# ### # # # # # ####### # # # # # #
|
|
||||||
# # # # # # # # # # # #
|
|
||||||
# # ############### # ####### ####### # # ####### #
|
|
||||||
# # # # # # # # # #
|
|
||||||
# # # ############# ####### ####### # # ####### # #
|
|
||||||
# # # # # # # # # # # #
|
|
||||||
# # # # ######### ####### # # ##### # ####### # # #
|
|
||||||
# # # # # # # # # # # # # #
|
|
||||||
##### # # ##### ####### # ##### # # # # ### # #####
|
|
||||||
# # # # # # # # # # # # #
|
|
||||||
# ##### ##### # # ############# # # # ### # ##### #
|
|
||||||
# # # # # # # # # # # # #
|
|
||||||
##### ##### # # # # ############# # ### # ##### # #
|
|
||||||
# # # # # # # # # # # # #
|
|
||||||
# # ##### # # # # ################### # ### # ### #
|
|
||||||
# # # # # # # # # # # # # #
|
|
||||||
# ##### # # # # # # ############### # ### # ### # #
|
|
||||||
# # # # # # # # # # # # #
|
|
||||||
##### # ######### ############### # ### # # ### # #
|
|
||||||
# # # # # # # # #
|
|
||||||
# ############# ##################### ####### # # #
|
|
||||||
# # # # #
|
|
||||||
############# ######################### ###########
|
|
||||||
# # # #
|
|
||||||
# ########### # ####################### # ####### #
|
|
||||||
# # # # # # #
|
|
||||||
########### # # # ####################### ####### #
|
|
||||||
# # # # ### #
|
|
||||||
# ########### ########################### #E# #
|
|
||||||
# ### #
|
|
||||||
###################################################
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
#Графики
|
|
||||||
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()
|
|
||||||
|
|
@ -1,596 +0,0 @@
|
||||||
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)
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
## ####S# ##
|
|
||||||
# ## # ##
|
|
||||||
## # # # #
|
|
||||||
# ### #
|
|
||||||
# ## ## E
|
|
||||||
# ##### ######
|
|
||||||
|
|
@ -1,128 +0,0 @@
|
||||||
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.
|
Before Width: | Height: | Size: 777 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 92 KiB |
|
|
@ -1,16 +0,0 @@
|
||||||
ëàáèðèíò;ñòðàòåãèÿ;âðåìÿ_ìñ;ïîñåùåíî_êëåòîê (ñð);äëèíà_ïóòè (ñð)
|
|
||||||
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,15 +0,0 @@
|
||||||
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
|
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user