forked from UNN/2026-rff_mp
Merge pull request '[1] task1' (#385) from kolesovve/2026-rff_mp:task1 into develop
Reviewed-on: UNN/2026-rff_mp#385
This commit is contained in:
commit
1853850bfb
61
kolesovve/task1/docs/data/bst.py
Normal file
61
kolesovve/task1/docs/data/bst.py
Normal 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, [])
|
||||
101
kolesovve/task1/docs/data/graphs.py
Normal file
101
kolesovve/task1/docs/data/graphs.py
Normal 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()
|
||||
37
kolesovve/task1/docs/data/hash_table.py
Normal file
37
kolesovve/task1/docs/data/hash_table.py
Normal 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
|
||||
60
kolesovve/task1/docs/data/linked_list.py
Normal file
60
kolesovve/task1/docs/data/linked_list.py
Normal 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
|
||||
197
kolesovve/task1/docs/data/main.py
Normal file
197
kolesovve/task1/docs/data/main.py
Normal 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")
|
||||
109
kolesovve/task1/docs/data/results.csv
Normal file
109
kolesovve/task1/docs/data/results.csv
Normal 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
|
||||
|
161
kolesovve/task1/docs/data/results.py
Normal file
161
kolesovve/task1/docs/data/results.py
Normal 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 создан!")
|
||||
BIN
kolesovve/task1/docs/отчет(1).docx
Normal file
BIN
kolesovve/task1/docs/отчет(1).docx
Normal file
Binary file not shown.
100
kolesovve/task2/docs/data/big_maze.txt
Normal file
100
kolesovve/task2/docs/data/big_maze.txt
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
####################################################################################################
|
||||
#S # # # ## ### ### ### ### ## # # # # ### # # ## ##### # # ### ## # #
|
||||
# ## # # ### # # ## # # # # ## ### # # # # # # # #### # ##### ## # # ##
|
||||
# ## ## # ### # # # #### # ## # # # # # ##### # ## # #
|
||||
# ### # # # ## ### # # # ### # # ## # # # # ## ### ## ## # # ## ##
|
||||
# ## ## # #### # ##### # # ## ## # # # # # ## # ## ## # #
|
||||
# ## # ## ## ### ### # # # # # ## ### ##### # # # ## ### ### # ### ## #
|
||||
# # # # # ## # ### # ## ### ## # # # ## # # # # #### # # ###
|
||||
# # ## # # # ### # ###### # # # # ### # ### ## # # # ## # # ## ##
|
||||
# # ## # # ## # # # ##### # # # # #### ## ### ### # # # ## # ## # ## ##
|
||||
# # # # ## # # ### # ## ## # # # # # ### # ## # ## ## # ## # # ## ##
|
||||
# ### ## # ### # ##### # # ### ### ## ## # # #### # # #### ## # ### # #
|
||||
# # #### # # ## ## # #### ## ## ## # # ## # # ### # # #### # ####### ###
|
||||
# # # # # # # # # # ### # # ###### # # # # # # # # ### #
|
||||
# ## # # # ## ### # #### ## ## # ## # # # # # # # # ### ## ## # # ## # # #
|
||||
# ## # ## # ### # #### # # ### ## # ### ## # # # ## # ###### #
|
||||
# # ### #### ## ### # ## ## ### # # # # # ## # ### # ## ###
|
||||
# # # # ##### # ### # # # # ## ### # #### # # # # # # # # # ## ## # #
|
||||
# # # ##### ## # # # # # # # #### # # # ## ### ### # # ## ### ###
|
||||
# # # # #### # # ###### # ## # # # ####### ## ## # # # # # # # # # ## #
|
||||
# ## # # ### # # # ## ### # #### ### # ## # ### ## ### ## ##
|
||||
# # ### # # # ## # # # ## ### # # ## # # # ## # # ### ## ### # # ##
|
||||
# ### # ## # # # # ## #### # ## ## # ### ## ## ## ## # # # # ### # ### ###
|
||||
# ## ## ## ### # ### ## # # # # # # # ## # ### # ## # # ## # # ## # #
|
||||
# ## ## ## ## # ####### ### ## ## ### ## # # # ## # # # ## # #
|
||||
# ## # # ## # ## # # # ## # # ### ### # # ## ## # #
|
||||
# ## # ## ### ## ## ### # ## # # # ## # #### # ## # # # # # # # #
|
||||
# # # #### # # # # # # ## # # ## #### # # ### # ## ## ## ### #
|
||||
# # ## # ## # # # ## ## # # ## ### # # ## # ## ### # # # #
|
||||
# # ## ## # ## ## # ## ### # # # # # ### # # ### # # # # ### # # ##
|
||||
# # # # # #### # # # # ### ##### ## # # ## # # # #### # # ### ## # #
|
||||
# ### ## ## # # # #### ## ## # # # # ## # ##### # # # ### ## # # # ## #
|
||||
# # # ### # ### # # # # # # # ## ## # # # ## ## # ## # # # ##
|
||||
# # # # # # ## # ## # # ## ## # ## # ### # # # #
|
||||
# # ## ### # # ## # ## #### # # ## # # ### ## # # ### ## ##
|
||||
# ##### ## # # # ### ##### ## # # # ## ## ### # # # # # #
|
||||
# # # ## ## # # ### ## ### ## # # ## ## ### # # # # # # # ###
|
||||
# ### ## # # # # ## ## # ## ##### # ### #### #### # # # # ## # # #
|
||||
# ### # ##### # ## ## # ## # ## # # # # ## # # # # # # ##
|
||||
# ## #### ## ## # ## ### ### # ## ###### # # # # # # ### # ## #
|
||||
# # ## # # # # # ## # # # # # # # ## ## #### # # ## ## ## ## # ## ## #
|
||||
# ## ## # ## ## ## ## # # ## # ## # # ## ####### ## # ## ### # ## #
|
||||
# ## # # ## ### # ## ## # ## ## # ## # # # # ### ##### #
|
||||
# # # ## # # ## # ## ### ## # ## ## # # ### # # # # ### #####
|
||||
# # ## # # # # # ## # ## # # # # # # # ## ##### ## # ## # #
|
||||
# # # ### # # # #### # # # # # # # ###### # # # # ### ## ## ###
|
||||
# ## # ## # ## # ## ## # # # # # ## ### ##### # # ############## #
|
||||
# # ## ## # # # ## # # # # # # ### ## # ## # ### # ### ### ### # # #
|
||||
# # ## ### #### ### # # # # # ### # # # # ### # # # ## # # # ########
|
||||
# # # # # ## ### ## ## ## ## # # # # # # # ## # ## ### ## # #
|
||||
# # ## # #### ## # ## ## ### # ## # ##### # ### ## # # ### # ###
|
||||
# #### # # # ## # ### # ### # # ### # # ## # ## # ## ## ##### # #
|
||||
# # #### # ## ## ###### ## # # # ## # #### # # # # # # ## # ## #
|
||||
# ### ######## ## # ## # # # ## #### # ### ### ## # ## ## # ## # ## ## #
|
||||
# # ## # ## ## # # ## ### # # # # # ### # # ## # # ## #
|
||||
# # # # ### # # # # ### # ## # # # # ### ## ## # ## ### # # ##
|
||||
# # # ### # # # # # # # # ## # # ## # # # ## ## # ###### # #
|
||||
# #### ## ## ## ## # # # # # # # ## ## ## # # ## # # # #
|
||||
# # ## # # # # # # # ### # # # # ##### # # ## ## ## # # ## # ## #
|
||||
# # # ## # ## ## ### # ### # # # # ### ### ## # ## # # # ## # ### # ##
|
||||
# ## # # # # # # # ## # ### ## ## ## # # # # ### # #### # ## ## # # ##
|
||||
# ### # ## # ### ## ## ## # # # # # # # # # ## # ### ## #
|
||||
# ### # #### # # # # # #### #### ### # # # ### # # # # # # ##
|
||||
# ## # # ### # ## ##### # # ##### # # # # ### # ### ## # # ## # #### #
|
||||
# #### # ##### # ### # # # # # # #### # ## # ## ## # ### # ## ### # #
|
||||
# # ## ## ### # # # # # ## # # ### # # ## # ## # # ###### # ### #### ##
|
||||
# ## ## # #### # # # # # ## # ### # #### ## ### # ### # # # ##
|
||||
# # ## # # # # ## ## ## # # # # # ### # ## ## ## # ## ## # # # # # ##
|
||||
# ## # # # # # # # # # ## # # ### # # # # #### ## # # # ###
|
||||
# ## ### ## # # # # ## # #### # ## # # ## #### ### ## # # #
|
||||
# # # # ## #### # ## # # # # ## # # ### # # ## ### # ## ## # # ##
|
||||
# # # # ## ## # ## ## #### # # ## ## ## ## # ## # # ## ### #
|
||||
# ## ##### # ## # # # ## ## #### # # # ## # ## ## ##### # # # # ## #
|
||||
# ## # ## # # # # # # ## # ## # # ## ## ### # # # # #
|
||||
# # # # # # ## # ## ### ## # # # # # # ### # #### ## # ## # ##
|
||||
# # #### ## # # ####### ### # # # ## ## # ## ## # # ## # #
|
||||
# ### # ### ##### # # # # # # ## # ### #### # ## # # # # # # ### # ##
|
||||
# ## ## # ### # # # # # # ## #### ## #### ### # # # ## ## # ##### # ##
|
||||
# ## # ## ## # # ### # # ### # # # # ## # # ### # # ## # ## # ## ## # #
|
||||
# ### ### # ## ### # # # # ## #### # # # ## # # # # # ## # #
|
||||
# ## # ## # # #### # # # # # # # # # # ## ## ## # # ## ## ### ## ##
|
||||
# ##### # # # ### #### ## # ## # ## # ### # # ## # # ## # #### ## #
|
||||
# ## # # # # ## # # ## # # ##### # # # # # # # # # ## # #
|
||||
# ### ## # # # ## # ## #### ## ## # # ## # # ## # #### # ### # # ## #
|
||||
# ### # # ## ## ## ## # # ## # # ## # # # # # # # # # # # # # #
|
||||
# ###### # ## # ### # ## # # # ## ## ## ### # # # # # # #####
|
||||
# ## ##### # ## # ## # ## ## ## ## # # # # ## # # # # # # # #
|
||||
# # ### #### # ## ## ### ## # # ## # ## ## # ## # # ## ## # # # ## ## # #
|
||||
# ### ## ### ### # # # # ## # # # # ## #### ## ### # # # #
|
||||
# ## ### # # # ## ## # ### # ### ######## # ## # # ## # # # ### ### #
|
||||
# ##### ## # # ### # ## # # ## ### ## # #### # ##### ## #### ## # # #
|
||||
# ## ## # # # # ### # # ## ### ####### # ## # ## # #### # ### ## # # #
|
||||
# # # ### # ## ## # # ### # # ## ## ## ######## # # # ## # ##### ## #
|
||||
# ## ###### ## # # ##### ### # # # # ## # ## # ## # # ## # ## # # #
|
||||
# # # # # # # # ### # # ### # # # # ## ## ## ## ## # ## ## # #
|
||||
# # ## #### #### ## # # # # #### # ## # # ## ## # # # # # # ## # # # ## # #
|
||||
# # # # # # # # # ## ## ## # ## # # # # # # ## # # # ##### # # ### #
|
||||
# ## # # # # # # ## # # ## ## # # # # ## ## # # ## #####
|
||||
# E#
|
||||
####################################################################################################
|
||||
46
kolesovve/task2/docs/data/builders.py
Normal file
46
kolesovve/task2/docs/data/builders.py
Normal 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
|
||||
88
kolesovve/task2/docs/data/generate_mazes.py
Normal file
88
kolesovve/task2/docs/data/generate_mazes.py
Normal 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("Все лабиринты созданы!")
|
||||
50
kolesovve/task2/docs/data/graphs.py
Normal file
50
kolesovve/task2/docs/data/graphs.py
Normal 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()
|
||||
128
kolesovve/task2/docs/data/main.py
Normal file
128
kolesovve/task2/docs/data/main.py
Normal 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Готово!")
|
||||
50
kolesovve/task2/docs/data/medium_maze.txt
Normal file
50
kolesovve/task2/docs/data/medium_maze.txt
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
##################################################
|
||||
#S # # ## # # # ## # #
|
||||
# ## # # ## # # # # # ###
|
||||
# # ## ## # # ## # # # #
|
||||
# ## # # # # ## # # ## ## # ## #
|
||||
# # # # # # # # # # # #
|
||||
# # ## # # # # # ## ### # # # ###
|
||||
# #### ### # # # # # # # # # #
|
||||
# # # # ### # # # # # # # #
|
||||
# ## # # # ## # # # # ### #
|
||||
# # # # # #### # ## # # # ## # #
|
||||
# # ## # # ## # ### ## # # #
|
||||
# # # # # ### ## # # # # #
|
||||
# # # ## # # ## ## # ## ##
|
||||
# # # ## # # # # ## # ##
|
||||
# # ### # ## # ## # # # ## #
|
||||
# ##### ## # ## # ## ### ## # #
|
||||
# # ## # # # ## ### # # #
|
||||
# ## # # ## ## # # ## ##
|
||||
# # # ## # # # # ####
|
||||
# ### #### #### ## # # # #
|
||||
# # # ## # # # # ## # # #
|
||||
# ## # ## # ## ### # # # ## # # #
|
||||
# ## ## # ## #### ## # # # ##
|
||||
# ## # ### ## ## ## # # # # #
|
||||
# # ### # ###### # # # ## # # # ## #
|
||||
# # # # # ## # # # ## # # # # # ##
|
||||
# # # ## # # ## # # # #
|
||||
# ### ## # # # ## # # # ## #
|
||||
# # # # ## # # # # # #
|
||||
# # # # ## #### # # # # ### #
|
||||
# # ### # # # ## # # # # # #
|
||||
# # ## # # # #### # # # #
|
||||
# # ### # # # # # # # # #
|
||||
# # # ## # # ## ### # ## #### #
|
||||
# ### # ## # # # ## ## ## ## #
|
||||
# # ## ### # # # # # #
|
||||
# ## # # # # # # # ## # # #
|
||||
# # # # # ## ## # ### ### # #
|
||||
# #### # # ## # ## # # ##
|
||||
# # # # ## ### ## # # # ##
|
||||
# # # ## # # # # # ### #
|
||||
# # # # ### # # #
|
||||
# # # # ## # # # ### ###
|
||||
# ## # # # # # # # # # # # #
|
||||
# # # # # # ## # ## #
|
||||
# # # # # # # ## # ## ####
|
||||
# ## # # # # # # # # # #####
|
||||
# E#
|
||||
##################################################
|
||||
68
kolesovve/task2/docs/data/model.py
Normal file
68
kolesovve/task2/docs/data/model.py
Normal 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)
|
||||
10
kolesovve/task2/docs/data/no_exit_maze.txt
Normal file
10
kolesovve/task2/docs/data/no_exit_maze.txt
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
##########
|
||||
#S # #
|
||||
# ### #
|
||||
# # #
|
||||
# # ##
|
||||
# # # ##
|
||||
# # ##
|
||||
# # #
|
||||
# # # # #
|
||||
##########
|
||||
10
kolesovve/task2/docs/data/no_wall_maze.txt
Normal file
10
kolesovve/task2/docs/data/no_wall_maze.txt
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
##########
|
||||
#S #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# E#
|
||||
##########
|
||||
58
kolesovve/task2/docs/data/observer_command.py
Normal file
58
kolesovve/task2/docs/data/observer_command.py
Normal 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
|
||||
21
kolesovve/task2/docs/data/result.py
Normal file
21
kolesovve/task2/docs/data/result.py
Normal 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)
|
||||
13
kolesovve/task2/docs/data/results.csv
Normal file
13
kolesovve/task2/docs/data/results.csv
Normal 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
|
||||
|
10
kolesovve/task2/docs/data/small_maze.txt
Normal file
10
kolesovve/task2/docs/data/small_maze.txt
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
##########
|
||||
#S # #
|
||||
# # #
|
||||
# ##
|
||||
# # ##
|
||||
# ###
|
||||
# # #
|
||||
# # #
|
||||
# E#
|
||||
##########
|
||||
42
kolesovve/task2/docs/data/solver.py
Normal file
42
kolesovve/task2/docs/data/solver.py
Normal 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)
|
||||
88
kolesovve/task2/docs/data/strategies.py
Normal file
88
kolesovve/task2/docs/data/strategies.py
Normal 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)
|
||||
BIN
kolesovve/task2/docs/Отчет(2).docx
Normal file
BIN
kolesovve/task2/docs/Отчет(2).docx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user