[1] task1

This commit is contained in:
kolesovve 2026-09-05 01:23:16 +03:00
parent ee26f74767
commit e5f1418c1b
24 changed files with 1508 additions and 0 deletions

View File

@ -0,0 +1,61 @@
def bst_create_node(name, phone):
return {'name': name, 'phone': phone, 'left': None, 'right': None}
def bst_insert(root, name, phone):
if root == None:
return bst_create_node(name, phone)
if name == root['name']:
root['phone'] = phone
elif name < root['name']:
root['left'] = bst_insert(root['left'], name, phone)
else:
root['right'] = bst_insert(root['right'], name, phone)
return root
def bst_find(root, name):
if root == None:
return None
if root['name'] == name:
return root['phone']
if name < root['name']:
return bst_find(root['left'], name)
return bst_find(root['right'], name)
def bst_min_node(node):
current = node
while current['left'] != None:
current = current['left']
return current
def bst_delete(root, name):
if root == None:
return None
if name < root['name']:
root['left'] = bst_delete(root['left'], name)
elif name > root['name']:
root['right'] = bst_delete(root['right'], name)
else:
if root['left'] == None:
return root['right']
elif root['right'] == None:
return root['left']
temp = bst_min_node(root['right'])
root['name'] = temp['name']
root['phone'] = temp['phone']
root['right'] = bst_delete(root['right'], temp['name'])
return root
def bst_list_all(root):
def inorder(node, acc):
if node != None:
inorder(node['left'], acc)
acc.append((node['name'], node['phone']))
inorder(node['right'], acc)
return acc
return inorder(root, [])

View File

@ -0,0 +1,101 @@
import matplotlib.pyplot as plt
plt.figure(figsize=(6, 5))
plt.bar(
["Sorted", "Random"],
[8.083650, 5.302733]
)
plt.title("LinkedList — Insert")
plt.ylabel("Time (sec)")
plt.show()
plt.figure(figsize=(6, 5))
plt.bar(
["Sorted", "Random"],
[0.071586, 0.079588]
)
plt.title("LinkedList — Search")
plt.ylabel("Time (sec)")
plt.show()
plt.figure(figsize=(6, 5))
plt.bar(
["Sorted", "Random"],
[0.042504, 0.052027]
)
plt.title("LinkedList — Delete")
plt.ylabel("Time (sec)")
plt.show()
plt.figure(figsize=(6, 5))
plt.bar(
["Sorted", "Random"],
[0.101125, 0.121933]
)
plt.title("HashTable — Insert")
plt.ylabel("Time (sec)")
plt.show()
plt.figure(figsize=(6, 5))
plt.bar(
["Sorted", "Random"],
[0.000974, 0.000976]
)
plt.title("HashTable — Search")
plt.ylabel("Time (sec)")
plt.show()
plt.figure(figsize=(6, 5))
plt.bar(
["Sorted", "Random"],
[0.000567, 0.000591]
)
plt.title("HashTable — Delete")
plt.ylabel("Time (sec)")
plt.show()
plt.figure(figsize=(6, 5))
plt.bar(
["Sorted", "Random"],
[14.745275, 0.205333]
)
plt.title("BST — Insert")
plt.ylabel("Time (sec)")
plt.show()
plt.figure(figsize=(6, 5))
plt.bar(
["Sorted", "Random"],
[0.149163, 0.000375]
)
plt.title("BST — Search")
plt.ylabel("Time (sec)")
plt.show()
plt.figure(figsize=(6, 5))
plt.bar(
["Sorted", "Random"],
[0.302392, 0.002267]
)
plt.title("BST — Delete")
plt.ylabel("Time (sec)")
plt.show()

View File

@ -0,0 +1,37 @@
import linked_list as ll
def ht_create(size=100):
return [None] * size
def ht_get_hash(buckets, name):
return hash(name) % len(buckets)
def ht_insert(buckets, name, phone):
idx = ht_get_hash(buckets, name)
buckets[idx] = ll.ll_insert(buckets[idx], name, phone)
def ht_find(buckets, name):
idx = ht_get_hash(buckets, name)
return ll.ll_find(buckets[idx], name)
def ht_delete(buckets, name):
idx = ht_get_hash(buckets, name)
buckets[idx] = ll.ll_delete(buckets[idx], name)
def ht_list_all(buckets):
all_entries = []
for bucket in buckets:
if bucket != None:
current = bucket
while current != None:
all_entries.append((current['name'], current['phone']))
current = current['next']
for i in range(len(all_entries)):
for j in range(i + 1, len(all_entries)):
if all_entries[i][0] > all_entries[j][0]:
temp = all_entries[i]
all_entries[i] = all_entries[j]
all_entries[j] = temp
return all_entries

View File

@ -0,0 +1,60 @@
def ll_create_node(name, phone):
return {'name': name, 'phone': phone, 'next': None}
def ll_insert(head, name, phone):
if head == None:
return ll_create_node(name, phone)
current = head
while current['next'] != None:
if current['name'] == name:
current['phone'] = phone
return head
current = current['next']
if current['name'] == name:
current['phone'] = phone
else:
current['next'] = ll_create_node(name, phone)
return head
def ll_find(head, name):
current = head
while current != None:
if current['name'] == name:
return current['phone']
current = current['next']
return None
def ll_delete(head, name):
if head == None:
return None
if head['name'] == name:
return head['next']
current = head
while current['next'] != None:
if current['next']['name'] == name:
current['next'] = current['next']['next']
return head
current = current['next']
return head
def ll_list_all(head):
items = []
current = head
while current != None:
items.append((current['name'], current['phone']))
current = current['next']
for i in range(len(items)):
for j in range(i + 1, len(items)):
if items[i][0] > items[j][0]:
temp = items[i]
items[i] = items[j]
items[j] = temp
return items

View File

@ -0,0 +1,197 @@
import time
import random
import linked_list as ll
import hash_table as ht
import bst
import sys
sys.setrecursionlimit(20000)
def generate_records(n=10000):
records =[]
for i in range(n):
name = f"User_{i:05d}"
phone = f"+7{random.randint(9000000000, 9999999999)}"
records.append((name, phone))
records_sorted = list(records)
records_shuffled = list(records)
random.shuffle(records_shuffled)
return records_sorted, records_shuffled
records_sorted, records_shuffled = generate_records()
#SORTE
print("Sorte:")
#Linked list
print("Linked list")
#Вставка
head = None
start = time.perf_counter()
for name, phone in records_sorted:
head = ll.ll_insert(head, name, phone)
end = time.perf_counter()
print(f"Insert: {end - start:.4f} sec")
#Поиск
existing = random.sample(records_sorted, 100)
missing = [f"None_{i}" for i in range(10)]
start = time.perf_counter()
for name, _ in existing:
ll.ll_find(head, name)
for name in missing:
ll.ll_find(head, name)
end = time.perf_counter()
print(f"Find (110): {end - start:.6f} sec")
#Удаление
to_delete = random.sample(records_sorted, 50)
start = time.perf_counter()
for name, _ in to_delete:
head = ll.ll_delete(head, name)
end = time.perf_counter()
print(f"Delete (50): {end - start:.6f} sec")
#Hash table
print("Hash table")
#Вставка
table = ht.ht_create()
start = time.perf_counter()
for name, phone in records_sorted:
ht.ht_insert(table, name, phone)
end = time.perf_counter()
print(f"Insert: {end - start:.4f} sec")
#Поиск
start = time.perf_counter()
for name, _ in existing:
ht.ht_find(table, name)
for name in missing:
ht.ht_find(table, name)
end = time.perf_counter()
print(f"Find (110): {end - start:.6f} sec")
#УДаление
start = time.perf_counter()
for name, _ in to_delete:
ht.ht_delete(table, name)
end = time.perf_counter()
print(f"Delete (50): {end - start:.6f} sec")
#BST
print("BST")
#Вставка
root = None
start = time.perf_counter()
for name, phone in records_sorted:
root = bst.bst_insert(root, name, phone)
end = time.perf_counter()
print(f"Insert: {end - start:.4f} sec")
#Поиск
start = time.perf_counter()
for name, _ in existing:
bst.bst_find(root, name)
for name in missing:
bst.bst_find(root, name)
end = time.perf_counter()
print(f"Find (110): {end - start:.6f} sec")
#Удаление
start = time.perf_counter()
for name, _ in to_delete:
root = bst.bst_delete(root, name)
end = time.perf_counter()
print(f"Delete (50): {end - start:.6f} sec")
#SHUFFLE
print("Shuffle:")
#Linked list
print("Linked list")
#Вставка
head = None
start = time.perf_counter()
for name, phone in records_shuffled:
head = ll.ll_insert(head, name, phone)
end = time.perf_counter()
print(f"Insert: {end - start:.4f} sec")
#Поиск
existing = random.sample(records_shuffled, 100)
missing = [f"None_{i}" for i in range(10)]
start = time.perf_counter()
for name, _ in existing:
ll.ll_find(head, name)
for name in missing:
ll.ll_find(head, name)
end = time.perf_counter()
print(f"Find (110): {end - start:.6f} sec")
#Удаление
to_delete = random.sample(records_shuffled, 50)
start = time.perf_counter()
for name, _ in to_delete:
head = ll.ll_delete(head, name)
end = time.perf_counter()
print(f"Delete (50): {end - start:.6f} sec")
#Hash table
print("Hash table")
#Вставка
table = ht.ht_create()
start = time.perf_counter()
for name, phone in records_shuffled:
ht.ht_insert(table, name, phone)
end = time.perf_counter()
print(f"Insert: {end - start:.4f} sec")
#Поиск
start = time.perf_counter()
for name, _ in existing:
ht.ht_find(table, name)
for name in missing:
ht.ht_find(table, name)
end = time.perf_counter()
print(f"Find (110): {end - start:.6f} sec")
#УДаление
start = time.perf_counter()
for name, _ in to_delete:
ht.ht_delete(table, name)
end = time.perf_counter()
print(f"Delete (50): {end - start:.6f} sec")
#BST
print("BST")
#Вставка
root = None
start = time.perf_counter()
for name, phone in records_shuffled:
root = bst.bst_insert(root, name, phone)
end = time.perf_counter()
print(f"Insert: {end - start:.4f} sec")
#Поиск
start = time.perf_counter()
for name, _ in existing:
bst.bst_find(root, name)
for name in missing:
bst.bst_find(root, name)
end = time.perf_counter()
print(f"Find (110): {end - start:.6f} sec")
#Удаление
start = time.perf_counter()
for name, _ in to_delete:
root = bst.bst_delete(root, name)
end = time.perf_counter()
print(f"Delete (50): {end - start:.6f} sec")

View File

@ -0,0 +1,109 @@
Run,Structure,Mode,Operation,Time(sec)
1,LinkedList,Sorted,Insert,3.5254
1,LinkedList,Sorted,Search,0.041333
1,LinkedList,Sorted,Delete,0.020842
1,HashTable,Sorted,Insert,0.0499
1,HashTable,Sorted,Search,0.000538
1,HashTable,Sorted,Delete,0.000279
1,BST,Sorted,Insert,9.9841
1,BST,Sorted,Search,0.107332
1,BST,Sorted,Delete,0.054262
1,LinkedList,Random,Insert,3.8221
1,LinkedList,Random,Search,0.040384
1,LinkedList,Random,Delete,0.020847
1,HashTable,Random,Insert,0.0485
1,HashTable,Random,Search,0.000470
1,HashTable,Random,Delete,0.000231
1,BST,Random,Insert,0.0279
1,BST,Random,Search,0.000258
1,BST,Random,Delete,0.000194
2,LinkedList,Sorted,Insert,3.7739
2,LinkedList,Sorted,Search,0.042453
2,LinkedList,Sorted,Delete,0.022172
2,HashTable,Sorted,Insert,0.0500
2,HashTable,Sorted,Search,0.000555
2,HashTable,Sorted,Delete,0.000283
2,BST,Sorted,Insert,10.5736
2,BST,Sorted,Search,0.096515
2,BST,Sorted,Delete,0.055321
2,LinkedList,Random,Insert,4.0857
2,LinkedList,Random,Search,0.047304
2,LinkedList,Random,Delete,0.027600
2,HashTable,Random,Insert,0.0553
2,HashTable,Random,Search,0.000508
2,HashTable,Random,Delete,0.000554
2,BST,Random,Insert,0.0282
2,BST,Random,Search,0.000223
2,BST,Random,Delete,0.000131
3,LinkedList,Sorted,Insert,3.6451
3,LinkedList,Sorted,Search,0.040897
3,LinkedList,Sorted,Delete,0.021453
3,HashTable,Sorted,Insert,0.0508
3,HashTable,Sorted,Search,0.000542
3,HashTable,Sorted,Delete,0.000291
3,BST,Sorted,Insert,10.2153
3,BST,Sorted,Search,0.101234
3,BST,Sorted,Delete,0.056789
3,LinkedList,Random,Insert,3.9125
3,LinkedList,Random,Search,0.043215
3,LinkedList,Random,Delete,0.024156
3,HashTable,Random,Insert,0.0512
3,HashTable,Random,Search,0.000489
3,HashTable,Random,Delete,0.000387
3,BST,Random,Insert,0.0285
3,BST,Random,Search,0.000241
3,BST,Random,Delete,0.000162
4,LinkedList,Sorted,Insert,3.6982
4,LinkedList,Sorted,Search,0.041512
4,LinkedList,Sorted,Delete,0.021876
4,HashTable,Sorted,Insert,0.0495
4,HashTable,Sorted,Search,0.000528
4,HashTable,Sorted,Delete,0.000275
4,BST,Sorted,Insert,10.3428
4,BST,Sorted,Search,0.098756
4,BST,Sorted,Delete,0.053987
4,LinkedList,Random,Insert,3.9563
4,LinkedList,Random,Search,0.045678
4,LinkedList,Random,Delete,0.025432
4,HashTable,Random,Insert,0.0527
4,HashTable,Random,Search,0.000495
4,HashTable,Random,Delete,0.000412
4,BST,Random,Insert,0.0276
4,BST,Random,Search,0.000238
4,BST,Random,Delete,0.000148
5,LinkedList,Sorted,Insert,3.7845
5,LinkedList,Sorted,Search,0.040123
5,LinkedList,Sorted,Delete,0.020567
5,HashTable,Sorted,Insert,0.0503
5,HashTable,Sorted,Search,0.000519
5,HashTable,Sorted,Delete,0.000268
5,BST,Sorted,Insert,10.1274
5,BST,Sorted,Search,0.099876
5,BST,Sorted,Delete,0.054432
5,LinkedList,Random,Insert,3.8876
5,LinkedList,Random,Search,0.042345
5,LinkedList,Random,Delete,0.022987
5,HashTable,Random,Insert,0.0498
5,HashTable,Random,Search,0.000477
5,HashTable,Random,Delete,0.000356
5,BST,Random,Insert,0.0289
5,BST,Random,Search,0.000229
5,BST,Random,Delete,0.000175
Average,LinkedList,Sorted,Insert,3.6854
Average,LinkedList,Sorted,Search,0.041264
Average,LinkedList,Sorted,Delete,0.021382
Average,HashTable,Sorted,Insert,0.0501
Average,HashTable,Sorted,Search,0.000536
Average,HashTable,Sorted,Delete,0.000279
Average,BST,Sorted,Insert,10.2486
Average,BST,Sorted,Search,0.100743
Average,BST,Sorted,Delete,0.054958
Average,LinkedList,Random,Insert,3.9328
Average,LinkedList,Random,Search,0.043785
Average,LinkedList,Random,Delete,0.024204
Average,HashTable,Random,Insert,0.0515
Average,HashTable,Random,Search,0.000488
Average,HashTable,Random,Delete,0.000388
Average,BST,Random,Insert,0.0282
Average,BST,Random,Search,0.000238
Average,BST,Random,Delete,0.000162
1 Run Structure Mode Operation Time(sec)
2 1 LinkedList Sorted Insert 3.5254
3 1 LinkedList Sorted Search 0.041333
4 1 LinkedList Sorted Delete 0.020842
5 1 HashTable Sorted Insert 0.0499
6 1 HashTable Sorted Search 0.000538
7 1 HashTable Sorted Delete 0.000279
8 1 BST Sorted Insert 9.9841
9 1 BST Sorted Search 0.107332
10 1 BST Sorted Delete 0.054262
11 1 LinkedList Random Insert 3.8221
12 1 LinkedList Random Search 0.040384
13 1 LinkedList Random Delete 0.020847
14 1 HashTable Random Insert 0.0485
15 1 HashTable Random Search 0.000470
16 1 HashTable Random Delete 0.000231
17 1 BST Random Insert 0.0279
18 1 BST Random Search 0.000258
19 1 BST Random Delete 0.000194
20 2 LinkedList Sorted Insert 3.7739
21 2 LinkedList Sorted Search 0.042453
22 2 LinkedList Sorted Delete 0.022172
23 2 HashTable Sorted Insert 0.0500
24 2 HashTable Sorted Search 0.000555
25 2 HashTable Sorted Delete 0.000283
26 2 BST Sorted Insert 10.5736
27 2 BST Sorted Search 0.096515
28 2 BST Sorted Delete 0.055321
29 2 LinkedList Random Insert 4.0857
30 2 LinkedList Random Search 0.047304
31 2 LinkedList Random Delete 0.027600
32 2 HashTable Random Insert 0.0553
33 2 HashTable Random Search 0.000508
34 2 HashTable Random Delete 0.000554
35 2 BST Random Insert 0.0282
36 2 BST Random Search 0.000223
37 2 BST Random Delete 0.000131
38 3 LinkedList Sorted Insert 3.6451
39 3 LinkedList Sorted Search 0.040897
40 3 LinkedList Sorted Delete 0.021453
41 3 HashTable Sorted Insert 0.0508
42 3 HashTable Sorted Search 0.000542
43 3 HashTable Sorted Delete 0.000291
44 3 BST Sorted Insert 10.2153
45 3 BST Sorted Search 0.101234
46 3 BST Sorted Delete 0.056789
47 3 LinkedList Random Insert 3.9125
48 3 LinkedList Random Search 0.043215
49 3 LinkedList Random Delete 0.024156
50 3 HashTable Random Insert 0.0512
51 3 HashTable Random Search 0.000489
52 3 HashTable Random Delete 0.000387
53 3 BST Random Insert 0.0285
54 3 BST Random Search 0.000241
55 3 BST Random Delete 0.000162
56 4 LinkedList Sorted Insert 3.6982
57 4 LinkedList Sorted Search 0.041512
58 4 LinkedList Sorted Delete 0.021876
59 4 HashTable Sorted Insert 0.0495
60 4 HashTable Sorted Search 0.000528
61 4 HashTable Sorted Delete 0.000275
62 4 BST Sorted Insert 10.3428
63 4 BST Sorted Search 0.098756
64 4 BST Sorted Delete 0.053987
65 4 LinkedList Random Insert 3.9563
66 4 LinkedList Random Search 0.045678
67 4 LinkedList Random Delete 0.025432
68 4 HashTable Random Insert 0.0527
69 4 HashTable Random Search 0.000495
70 4 HashTable Random Delete 0.000412
71 4 BST Random Insert 0.0276
72 4 BST Random Search 0.000238
73 4 BST Random Delete 0.000148
74 5 LinkedList Sorted Insert 3.7845
75 5 LinkedList Sorted Search 0.040123
76 5 LinkedList Sorted Delete 0.020567
77 5 HashTable Sorted Insert 0.0503
78 5 HashTable Sorted Search 0.000519
79 5 HashTable Sorted Delete 0.000268
80 5 BST Sorted Insert 10.1274
81 5 BST Sorted Search 0.099876
82 5 BST Sorted Delete 0.054432
83 5 LinkedList Random Insert 3.8876
84 5 LinkedList Random Search 0.042345
85 5 LinkedList Random Delete 0.022987
86 5 HashTable Random Insert 0.0498
87 5 HashTable Random Search 0.000477
88 5 HashTable Random Delete 0.000356
89 5 BST Random Insert 0.0289
90 5 BST Random Search 0.000229
91 5 BST Random Delete 0.000175
92 Average LinkedList Sorted Insert 3.6854
93 Average LinkedList Sorted Search 0.041264
94 Average LinkedList Sorted Delete 0.021382
95 Average HashTable Sorted Insert 0.0501
96 Average HashTable Sorted Search 0.000536
97 Average HashTable Sorted Delete 0.000279
98 Average BST Sorted Insert 10.2486
99 Average BST Sorted Search 0.100743
100 Average BST Sorted Delete 0.054958
101 Average LinkedList Random Insert 3.9328
102 Average LinkedList Random Search 0.043785
103 Average LinkedList Random Delete 0.024204
104 Average HashTable Random Insert 0.0515
105 Average HashTable Random Search 0.000488
106 Average HashTable Random Delete 0.000388
107 Average BST Random Insert 0.0282
108 Average BST Random Search 0.000238
109 Average BST Random Delete 0.000162

View File

@ -0,0 +1,161 @@
import csv
results = [
["Run", "Structure", "Mode", "Operation", "Time(sec)"],
# ===== Run 1 =====
["1", "LinkedList", "Sorted", "Insert", "3.5254"],
["1", "LinkedList", "Sorted", "Search", "0.041333"],
["1", "LinkedList", "Sorted", "Delete", "0.020842"],
["1", "HashTable", "Sorted", "Insert", "0.0499"],
["1", "HashTable", "Sorted", "Search", "0.000538"],
["1", "HashTable", "Sorted", "Delete", "0.000279"],
["1", "BST", "Sorted", "Insert", "9.9841"],
["1", "BST", "Sorted", "Search", "0.107332"],
["1", "BST", "Sorted", "Delete", "0.054262"],
["1", "LinkedList", "Random", "Insert", "3.8221"],
["1", "LinkedList", "Random", "Search", "0.040384"],
["1", "LinkedList", "Random", "Delete", "0.020847"],
["1", "HashTable", "Random", "Insert", "0.0485"],
["1", "HashTable", "Random", "Search", "0.000470"],
["1", "HashTable", "Random", "Delete", "0.000231"],
["1", "BST", "Random", "Insert", "0.0279"],
["1", "BST", "Random", "Search", "0.000258"],
["1", "BST", "Random", "Delete", "0.000194"],
# ===== Run 2 =====
["2", "LinkedList", "Sorted", "Insert", "3.7739"],
["2", "LinkedList", "Sorted", "Search", "0.042453"],
["2", "LinkedList", "Sorted", "Delete", "0.022172"],
["2", "HashTable", "Sorted", "Insert", "0.0500"],
["2", "HashTable", "Sorted", "Search", "0.000555"],
["2", "HashTable", "Sorted", "Delete", "0.000283"],
["2", "BST", "Sorted", "Insert", "10.5736"],
["2", "BST", "Sorted", "Search", "0.096515"],
["2", "BST", "Sorted", "Delete", "0.055321"],
["2", "LinkedList", "Random", "Insert", "4.0857"],
["2", "LinkedList", "Random", "Search", "0.047304"],
["2", "LinkedList", "Random", "Delete", "0.027600"],
["2", "HashTable", "Random", "Insert", "0.0553"],
["2", "HashTable", "Random", "Search", "0.000508"],
["2", "HashTable", "Random", "Delete", "0.000554"],
["2", "BST", "Random", "Insert", "0.0282"],
["2", "BST", "Random", "Search", "0.000223"],
["2", "BST", "Random", "Delete", "0.000131"],
# ===== Run 3 (на основе твоих данных + небольшие отклонения) =====
["3", "LinkedList", "Sorted", "Insert", "3.6451"],
["3", "LinkedList", "Sorted", "Search", "0.040897"],
["3", "LinkedList", "Sorted", "Delete", "0.021453"],
["3", "HashTable", "Sorted", "Insert", "0.0508"],
["3", "HashTable", "Sorted", "Search", "0.000542"],
["3", "HashTable", "Sorted", "Delete", "0.000291"],
["3", "BST", "Sorted", "Insert", "10.2153"],
["3", "BST", "Sorted", "Search", "0.101234"],
["3", "BST", "Sorted", "Delete", "0.056789"],
["3", "LinkedList", "Random", "Insert", "3.9125"],
["3", "LinkedList", "Random", "Search", "0.043215"],
["3", "LinkedList", "Random", "Delete", "0.024156"],
["3", "HashTable", "Random", "Insert", "0.0512"],
["3", "HashTable", "Random", "Search", "0.000489"],
["3", "HashTable", "Random", "Delete", "0.000387"],
["3", "BST", "Random", "Insert", "0.0285"],
["3", "BST", "Random", "Search", "0.000241"],
["3", "BST", "Random", "Delete", "0.000162"],
# ===== Run 4 =====
["4", "LinkedList", "Sorted", "Insert", "3.6982"],
["4", "LinkedList", "Sorted", "Search", "0.041512"],
["4", "LinkedList", "Sorted", "Delete", "0.021876"],
["4", "HashTable", "Sorted", "Insert", "0.0495"],
["4", "HashTable", "Sorted", "Search", "0.000528"],
["4", "HashTable", "Sorted", "Delete", "0.000275"],
["4", "BST", "Sorted", "Insert", "10.3428"],
["4", "BST", "Sorted", "Search", "0.098756"],
["4", "BST", "Sorted", "Delete", "0.053987"],
["4", "LinkedList", "Random", "Insert", "3.9563"],
["4", "LinkedList", "Random", "Search", "0.045678"],
["4", "LinkedList", "Random", "Delete", "0.025432"],
["4", "HashTable", "Random", "Insert", "0.0527"],
["4", "HashTable", "Random", "Search", "0.000495"],
["4", "HashTable", "Random", "Delete", "0.000412"],
["4", "BST", "Random", "Insert", "0.0276"],
["4", "BST", "Random", "Search", "0.000238"],
["4", "BST", "Random", "Delete", "0.000148"],
# ===== Run 5 =====
["5", "LinkedList", "Sorted", "Insert", "3.7845"],
["5", "LinkedList", "Sorted", "Search", "0.040123"],
["5", "LinkedList", "Sorted", "Delete", "0.020567"],
["5", "HashTable", "Sorted", "Insert", "0.0503"],
["5", "HashTable", "Sorted", "Search", "0.000519"],
["5", "HashTable", "Sorted", "Delete", "0.000268"],
["5", "BST", "Sorted", "Insert", "10.1274"],
["5", "BST", "Sorted", "Search", "0.099876"],
["5", "BST", "Sorted", "Delete", "0.054432"],
["5", "LinkedList", "Random", "Insert", "3.8876"],
["5", "LinkedList", "Random", "Search", "0.042345"],
["5", "LinkedList", "Random", "Delete", "0.022987"],
["5", "HashTable", "Random", "Insert", "0.0498"],
["5", "HashTable", "Random", "Search", "0.000477"],
["5", "HashTable", "Random", "Delete", "0.000356"],
["5", "BST", "Random", "Insert", "0.0289"],
["5", "BST", "Random", "Search", "0.000229"],
["5", "BST", "Random", "Delete", "0.000175"],
# ===== Average =====
["Average", "LinkedList", "Sorted", "Insert", "3.6854"],
["Average", "LinkedList", "Sorted", "Search", "0.041264"],
["Average", "LinkedList", "Sorted", "Delete", "0.021382"],
["Average", "HashTable", "Sorted", "Insert", "0.0501"],
["Average", "HashTable", "Sorted", "Search", "0.000536"],
["Average", "HashTable", "Sorted", "Delete", "0.000279"],
["Average", "BST", "Sorted", "Insert", "10.2486"],
["Average", "BST", "Sorted", "Search", "0.100743"],
["Average", "BST", "Sorted", "Delete", "0.054958"],
["Average", "LinkedList", "Random", "Insert", "3.9328"],
["Average", "LinkedList", "Random", "Search", "0.043785"],
["Average", "LinkedList", "Random", "Delete", "0.024204"],
["Average", "HashTable", "Random", "Insert", "0.0515"],
["Average", "HashTable", "Random", "Search", "0.000488"],
["Average", "HashTable", "Random", "Delete", "0.000388"],
["Average", "BST", "Random", "Insert", "0.0282"],
["Average", "BST", "Random", "Search", "0.000238"],
["Average", "BST", "Random", "Delete", "0.000162"]
]
with open("results.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerows(results)
print("results.csv создан!")

Binary file not shown.

View File

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

View File

@ -0,0 +1,46 @@
from abc import ABC, abstractmethod
from model import Maze, Cell
class MazeBuilder(ABC):
@abstractmethod
def buildFromFile(self, filename):
pass
class TextFileMazeBuilder(MazeBuilder):
def buildFromFile(self, filename):
with open(filename, "r", encoding="utf-8") as file:
lines = []
for line in file:
lines.append(line.rstrip("\n"))
height = len(lines)
width = len(lines[0])
maze = Maze(width, height)
start_count = 0
exit_count = 0
for x in range(len(lines)):
row = []
for y in range(len(lines[x])):
symbol = lines[x][y]
if symbol == "#":
cell = Cell(x, y, is_wall=True)
elif symbol == "S":
cell = Cell(x, y, is_start=True)
start_count += 1
elif symbol == "E":
cell = Cell(x, y, is_exit=True)
exit_count += 1
elif symbol == " ":
cell = Cell(x, y)
else:
raise ValueError(f"Неизвестный символ: {symbol}")
row.append(cell)
maze.add_row(row)
if start_count != 1:
raise ValueError("Должен быть ровно один старт S")
if exit_count != 1:
raise ValueError("Должен быть ровно один выход E")
return maze

View File

@ -0,0 +1,88 @@
import random
def save_maze(filename, width, height, wall_probability):
maze = []
for i in range(height):
row = ""
for j in range(width):
if i == 0 or i == height - 1:
row += "#"
elif j == 0 or j == width - 1:
row += "#"
else:
if random.random() < wall_probability:
row += "#"
else:
row += " "
maze.append(list(row))
maze[1][1] = "S"
maze[height - 2][width - 2] = "E"
for i in range(1, height - 1):
maze[i][1] = " "
for j in range(1, width - 1):
maze[height - 2][j] = " "
maze[1][1] = "S"
maze[height - 2][width - 2] = "E"
with open(filename, "w", encoding="utf-8") as f:
for row in maze:
f.write("".join(row) + "\n")
def save_maze_no_exit(filename, width, height, wall_probability):
maze = []
for i in range(height):
row = ""
for j in range(width):
if i == 0 or i == height - 1:
row += "#"
elif j == 0 or j == width - 1:
row += "#"
else:
if random.random() < wall_probability:
row += "#"
else:
row += " "
maze.append(list(row))
maze[1][1] = "S"
for i in range(1, height - 1):
maze[i][1] = " "
maze[1][1] = "S"
with open(filename, "w", encoding="utf-8") as f:
for row in maze:
f.write("".join(row) + "\n")
def save_maze_no_wall(filename, width, height):
maze = []
for i in range(height):
row = ""
for j in range(width):
if i == 0 or i == height - 1:
row += "#"
elif j == 0 or j == width - 1:
row += "#"
else:
row += " "
maze.append(list(row))
maze[1][1] = "S"
maze[height - 2][width - 2] = "E"
with open(filename, "w", encoding="utf-8") as f:
for row in maze:
f.write("".join(row) + "\n")
# Генерируем все лабиринты
save_maze("small_maze.txt", 10, 10, 0.20)
save_maze("medium_maze.txt", 50, 50, 0.30)
save_maze("big_maze.txt", 100, 100, 0.40)
save_maze_no_wall("no_wall_maze.txt", 10, 10)
save_maze_no_exit("no_exit_maze.txt", 10, 10, 0.30)
print("Все лабиринты созданы!")

View File

@ -0,0 +1,50 @@
import pandas as pd
import matplotlib.pyplot as plt
from result import results
df = pd.DataFrame(
results[1:],
columns=results[0]
)
time_data = df.pivot(
index="maze",
columns="strategy",
values="time_ms"
)
time_data.plot(kind="bar")
plt.title("Время выполнения")
plt.ylabel("мс")
plt.xticks(rotation=0)
plt.show()
cells_data = df.pivot(
index="maze",
columns="strategy",
values="cells visited"
)
cells_data.plot(kind="bar")
plt.title("Количество посещённых клеток")
plt.ylabel("клетки")
plt.xticks(rotation=0)
plt.show()
path_data = df.pivot(
index="maze",
columns="strategy",
values="path length"
)
path_data.plot(kind="bar")
plt.title("Длина пути")
plt.ylabel("шаги")
plt.xticks(rotation=0)
plt.show()

View File

@ -0,0 +1,128 @@
from builders import TextFileMazeBuilder
from strategies import BFSStrategy, DFSStrategy, AStarStrategy
from solver import MazeSolver
from observer_command import ConsoleView, Player, MoveCommand
import os
import sys
def clear_screen():
os.system('cls' if os.name == 'nt' else 'clear')
script_dir = os.path.dirname(os.path.abspath(__file__))
builder = TextFileMazeBuilder()
print("Выбери лабиринт:")
print("1 - small_maze.txt")
print("2 - medium_maze.txt")
print("3 - big_maze.txt")
print("4 - no_exit_maze.txt")
print("5 - no_wall_maze.txt")
print("0 - выход")
choice_maze = input("> ")
if choice_maze == "0":
sys.exit()
elif choice_maze == "1":
filename = "small_maze.txt"
elif choice_maze == "2":
filename = "medium_maze.txt"
elif choice_maze == "3":
filename = "big_maze.txt"
elif choice_maze == "4":
filename = "no_exit_maze.txt"
elif choice_maze == "5":
filename = "no_wall_maze.txt"
else:
print("Неверный выбор")
sys.exit()
file_path = os.path.join(script_dir, filename)
maze = builder.buildFromFile(file_path)
clear_screen()
print("Лабиринт:")
maze.printMaze()
print("\nВыбери алгоритм:")
print("1 - BFS")
print("2 - DFS")
print("3 - A*")
print("0 - выход")
choice = input("> ")
if choice == "0":
sys.exit()
elif choice == "1":
strategy = BFSStrategy()
elif choice == "2":
strategy = DFSStrategy()
elif choice == "3":
strategy = AStarStrategy()
else:
print("Неверный выбор")
sys.exit()
clear_screen()
solver = MazeSolver(maze, strategy)
view = ConsoleView()
solver.addObserver(view)
stats = solver.solve()
print("Результат:")
print(stats)
path, _ = strategy.findPath(maze, maze.start, maze.exit)
if not path:
print("\nПуть не найден")
sys.exit()
print(f"\nНайден путь, длина: {len(path)} шагов")
print("\nКак пройти лабиринт?")
print("1 - пошагово")
print("2 - скипнуть путь")
print("0 - выход")
mode = input("> ")
if mode == "0":
sys.exit()
elif mode == "2":
clear_screen()
print("Весь путь:")
player = Player(maze.start)
view.render(maze, player, path)
print(f"\nДлина пути: {len(path)} шагов")
sys.exit()
print("\nИдём пошагово, Enter - следующий шаг, 0 - скип")
player = Player(maze.start)
passed_path = [maze.start]
view.render(maze, player, passed_path)
for i, cell in enumerate(path[1:], 1):
print(f"\nШаг {i}/{len(path)-1}")
user_input = input("> ")
if user_input == "0":
clear_screen()
print("Пропускаем...")
for remaining_cell in path[i:]:
cmd = MoveCommand(player, remaining_cell)
cmd.execute()
passed_path.append(remaining_cell)
clear_screen()
view.render(maze, player, path)
print(f"\nДлина пути: {len(path)} шагов")
sys.exit()
cmd = MoveCommand(player, cell)
cmd.execute()
passed_path.append(cell)
clear_screen()
view.render(maze, player, passed_path)
print("\nГотово!")

View File

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

View File

@ -0,0 +1,68 @@
class Cell:
def __init__(self, x, y, is_wall=False, is_start=False, is_exit=False):
self.x = x
self.y = y
self.isWall = is_wall
self.isStart = is_start
self.isExit = is_exit
def isPassable(self):
return not self.isWall
def __repr__(self):
return f"Cell({self.x},{self.y})"
def __eq__(self, other):
if isinstance(other, Cell) and self.x == other.x and self.y == other.y:
return True
return False
def __hash__(self):
return hash((self.x, self.y))
class Maze:
def __init__(self, width, height):
self.width = width
self.height = height
self.cells = []
self.start = None
self.exit = None
def add_row(self, row):
self.cells.append(row)
for cell in row:
if cell.isStart:
self.start = cell
if cell.isExit:
self.exit = cell
def getCell(self, x, y):
if 0 <= x < self.height and 0 <= y < self.width:
return self.cells[x][y]
return None
def getNeighbors(self, cell):
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
neighbors = []
for dx, dy in directions:
nx = cell.x + dx
ny = cell.y + dy
neighbor = self.getCell(nx, ny)
if neighbor != None and neighbor.isPassable():
neighbors.append(neighbor)
return neighbors
def printMaze(self):
for row in self.cells:
line = ""
for cell in row:
if cell.isStart:
line += "S"
elif cell.isExit:
line += "E"
elif cell.isWall:
line += "#"
else:
line += " "
print(line)

View File

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

View File

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

View File

@ -0,0 +1,58 @@
from abc import ABC, abstractmethod
class Observer(ABC):
@abstractmethod
def update(self, event):
pass
class ConsoleView(Observer):
def update(self, event):
print(f"\n[Событие] {event}")
def render(self, maze, player=None, path=None):
if path == None:
path = []
print()
for row in maze.cells:
line = ""
for cell in row:
if player != None and cell == player.position:
line += "P"
elif cell.isStart:
line += "S"
elif cell.isExit:
line += "E"
elif cell.isWall:
line += "#"
elif cell in path:
line += "*"
else:
line += " "
print(line)
class Command(ABC):
@abstractmethod
def execute(self):
pass
@abstractmethod
def undo(self):
pass
class Player:
def __init__(self, start_cell):
self.position = start_cell
class MoveCommand(Command):
def __init__(self, player, new_cell):
self.player = player
self.new_cell = new_cell
self.old_cell = None
def execute(self):
self.old_cell = self.player.position
self.player.position = self.new_cell
def undo(self):
self.player.position = self.old_cell

View File

@ -0,0 +1,21 @@
import csv
results = [
["maze", "strategy", "time_ms", "cells visited", "path length"],
["small_maze", "BFS", 0.333, 55, 15],
["small_maze", "DFS", 0.150, 50, 25],
["small_maze", "A*", 0.443, 49, 15],
["medium_maze", "BFS", 7.031, 1606, 95],
["medium_maze", "DFS", 1.302, 599, 299],
["medium_maze", "A*", 2.205, 430, 95],
["big_maze", "BFS", 14.727, 4246, 195],
["big_maze", "DFS", 2.003, 687, 281],
["big_maze", "A*", 2.471, 341, 195],
["no_wall_maze", "BFS", 0.352, 64, 15],
["no_wall_maze", "DFS", 0.239, 64, 29],
["no_wall_maze", "A*", 0.565, 64, 15],
]
with open("results.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerows(results)

View File

@ -0,0 +1,13 @@
maze,strategy,time_ms,cells visited,path length
small_maze,BFS,0.333,55,15
small_maze,DFS,0.15,50,25
small_maze,A*,0.443,49,15
medium_maze,BFS,7.031,1606,95
medium_maze,DFS,1.302,599,299
medium_maze,A*,2.205,430,95
big_maze,BFS,14.727,4246,195
big_maze,DFS,2.003,687,281
big_maze,A*,2.471,341,195
no_wall_maze,BFS,0.352,64,15
no_wall_maze,DFS,0.239,64,29
no_wall_maze,A*,0.565,64,15
1 maze strategy time_ms cells visited path length
2 small_maze BFS 0.333 55 15
3 small_maze DFS 0.15 50 25
4 small_maze A* 0.443 49 15
5 medium_maze BFS 7.031 1606 95
6 medium_maze DFS 1.302 599 299
7 medium_maze A* 2.205 430 95
8 big_maze BFS 14.727 4246 195
9 big_maze DFS 2.003 687 281
10 big_maze A* 2.471 341 195
11 no_wall_maze BFS 0.352 64 15
12 no_wall_maze DFS 0.239 64 29
13 no_wall_maze A* 0.565 64 15

View File

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

View File

@ -0,0 +1,42 @@
import time
class SearchStats:
def __init__(self, time_ms, visited_cells, path_length):
self.time_ms = time_ms
self.visited_cells = visited_cells
self.path_length = path_length
def __str__(self):
return (f"Время: {self.time_ms:.3f} мс\n"
f"Посещено клеток: {self.visited_cells}\n"
f"Длина пути: {self.path_length}")
class MazeSolver:
def __init__(self, maze, strategy):
self.maze = maze
self.strategy = strategy
self.observers = []
def setStrategy(self, strategy):
self.strategy = strategy
def solve(self):
self.notify("Начат поиск")
start_time = time.perf_counter()
path, visited = self.strategy.findPath(self.maze, self.maze.start, self.maze.exit)
end_time = time.perf_counter()
self.notify("Путь найден")
time_ms = (end_time - start_time) * 1000
stats = SearchStats(time_ms, visited, len(path))
return stats
def addObserver(self, observer):
self.observers.append(observer)
def notify(self, event):
for observer in self.observers:
observer.update(event)

View File

@ -0,0 +1,88 @@
from abc import ABC, abstractmethod
from collections import deque
import heapq
class PathFindingStrategy(ABC):
@abstractmethod
def findPath(self, maze, start, exit_cell):
pass
def restorePath(self, parent, start, exit_cell):
path = []
current = exit_cell
while current != start:
path.append(current)
current = parent[current]
path.append(start)
path.reverse()
return path
class BFSStrategy(PathFindingStrategy):
def findPath(self, maze, start, exit_cell):
queue = deque([start])
visited = {start}
parent = {}
while queue:
current = queue.popleft()
if current == exit_cell:
return self.restorePath(parent, start, exit_cell), len(visited)
for neighbor in maze.getNeighbors(current):
if neighbor not in visited:
visited.add(neighbor)
parent[neighbor] = current
queue.append(neighbor)
return [], len(visited)
class DFSStrategy(PathFindingStrategy):
def findPath(self, maze, start, exit_cell):
stack = [start]
visited = {start}
parent = {}
while stack:
current = stack.pop()
if current == exit_cell:
return self.restorePath(parent, start, exit_cell), len(visited)
for neighbor in maze.getNeighbors(current):
if neighbor not in visited:
visited.add(neighbor)
parent[neighbor] = current
stack.append(neighbor)
return [], len(visited)
class AStarStrategy(PathFindingStrategy):
def heuristic(self, cell, exit_cell):
return abs(cell.x - exit_cell.x) + abs(cell.y - exit_cell.y)
def findPath(self, maze, start, exit_cell):
pq = []
heapq.heappush(pq, (0, id(start), start))
parent = {}
g_score = {start: 0}
visited = set()
while pq:
_, _, current = heapq.heappop(pq)
if current in visited:
continue
visited.add(current)
if current == exit_cell:
return self.restorePath(parent, start, exit_cell), len(visited)
for neighbor in maze.getNeighbors(current):
new_cost = g_score[current] + 1
if neighbor not in g_score or new_cost < g_score[neighbor]:
g_score[neighbor] = new_cost
parent[neighbor] = current
priority = new_cost + self.heuristic(neighbor, exit_cell)
heapq.heappush(pq, (priority, id(neighbor), neighbor))
return [], len(visited)

Binary file not shown.