Rewrote all 3 algorithms. Generated 10 random graphs and grids for tests. Created testing structure which uses generated graphs and grids as input data to algorithms, measures execution time and memory blocks used by them. Takes these measurements and found weights and builds tables in latex format which compare these data among those three algorithms.

This commit is contained in:
Bartosz 2022-09-25 16:41:41 +02:00
parent e9cda32103
commit a530372141
31 changed files with 1450794 additions and 424 deletions

View File

@ -1,9 +1,2 @@
pip install fibheap pip install fibheap
dijkstry:<br>
https://pl.wikipedia.org/wiki/Algorytm_Dijkstry
kopce:<br>
https://ufkapano.github.io/algorytmy/lekcja09/heap.html
https://docs.python.org/3/library/heapq.html

View File

@ -1,101 +1,71 @@
import fibheap import fibheap
import math
def heuristic_cost(start, goal, graph): def heuristic_cost(node1, node2):
return 0 return 0
def a_star_algorithm(graph, start, goal, h=heuristic_cost, is_directed=False): def heuristic_cost_manhattan(node1, node2):
def return_path_and_weight(c_f, c, s): part1 = (node1[0]-node2[0])**2
current_node = c_f[c] part1 = part1
shortest_path = [c, current_node] part2 = (node1[1]-node2[1])**2
while current_node != s: return math.sqrt(part1 + part2)
current_node = c_f[current_node]
shortest_path.append(current_node)
weight = 0 def a_star_algorithm(s, t, N, A, w, h):
shortest_path.reverse() if s == t:
for k in range(len(shortest_path) - 1): return [s], 0
if not is_directed:
if shortest_path[k] > shortest_path[k+1]: H = fibheap.makefheap()
weight += graph[(shortest_path[k], shortest_path[k+1])] d = {}
heap_node_connection = {}
pred = {}
f = {}
for i in N:
d[i] = float('inf')
d[s] = 0
f[s] = d[s] + h(s, t)
pred[s] = None
heap_node_connection[s] = fibheap.fheappush(H, 0, s)
success = False
while H.num_nodes > 0:
i = fibheap.fheappop(H)[1]
if i == t:
success = True
break
for j in A[i]:
path_sum = d[i] + w[(i, j)]
if d[j] > path_sum:
pred[j] = i
f[j] = path_sum + h(j, t)
if d[j] == float('inf'):
d[j] = path_sum
heap_node_connection[j] = fibheap.fheappush(H, f[j], j)
else: else:
weight += graph[(shortest_path[k + 1], shortest_path[k])] d[j] = path_sum
else: H.decrease_key(heap_node_connection[j], f[j])
weight += graph[(shortest_path[k], shortest_path[k + 1])] if success:
return shortest_path, weight path = [t]
current_node = t
point_set = dict() while pred[current_node] is not None:
for arc in g.keys(): path.append(pred[current_node])
point_set[arc[0]] = [] current_node = pred[current_node]
point_set[arc[1]] = [] path.reverse()
return path, d[t]
for arc in graph.keys(): return None, None
point_set[arc[0]].append(arc[1])
if not is_directed:
point_set[arc[1]].append(arc[0])
pred = dict()
node_heap = fibheap.makefheap()
fibheap.fheappush(node_heap, 0, start)
g_score = {k: float('inf') for k in point_set.keys()}
g_score[start] = 0
f_score = {k: float('inf') for k in point_set.keys()}
f_score[start] = h(start, goal, graph)
while node_heap.num_nodes > 0:
# current = list(open_set)[0]
# for k in open_set:
# if f_score[k] < f_score[current]:
# current = k
current = fibheap.fheappop(node_heap)
if current[1] == goal:
return return_path_and_weight(pred, goal, start)
for neighbor in point_set[current[1]]:
tentative_g_score = g_score[current[1]]
if not is_directed:
if current[1] > neighbor:
tentative_g_score += graph[(current[1], neighbor)]
else:
tentative_g_score += graph[(neighbor, current[1])]
else:
tentative_g_score += graph[(current[1], neighbor)]
if tentative_g_score < g_score[neighbor]:
g_score[neighbor] = tentative_g_score
f_score[neighbor] = g_score[neighbor] + h(neighbor, goal, graph)
fibheap.fheappush(node_heap, f_score[neighbor], neighbor)
pred[neighbor] = current[1]
if __name__ == "__main__": if __name__ == "__main__":
g = { N = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
(2, 1): 3, A = {1: [2, 8, 6], 2: [1, 3, 5], 8: [1, 4], 3: [2], 5: [2, 7, 9, 10], 4: [6, 7, 8], 6: [4, 1], 7: [4, 5], 9: [5], 10: [5]}
(3, 2): 2, A_b = {2: [1, 3, 5], 1: [2, 8, 6], 8: [1, 4], 3: [2], 5: [2, 7, 9, 10], 6: [4, 1], 4: [6, 7, 8], 7: [4, 5], 9: [5], 10: [5]}
(5, 3): 1, w = {(1, 2): 84, (2, 1): 84, (1, 8): 52, (8, 1): 52, (2, 3): 4, (3, 2): 4, (2, 5): 39, (5, 2): 39, (4, 6): 74, (6, 4): 74, (4, 7): 81, (7, 4): 81, (5, 7): 45, (7, 5): 45, (5, 9): 66, (9, 5): 66, (5, 10): 19, (10, 5): 19, (4, 8): 87, (8, 4): 87, (1, 6): 4, (6, 1): 4}
(9, 5): 5, print(a_star_algorithm(1, 10, N, A, w, heuristic_cost))
(10, 9): 4,
(9, 4): 3,
(4, 1): 4,
(7, 1): 6,
(3, 1): 4,
(6, 2): 3,
(8, 6): 8,
(8, 3): 2,
(9, 1): 8
}
g2 = { N = {(3, 4), (5, 7), (7, 7), (6, 5), (4, 5), (3, 3), (4, 8), (3, 6), (8, 5), (6, 4), (6, 7), (3, 5), (5, 5), (5, 8), (8, 7), (2, 6), (6, 6), (7, 5), (7, 8)}
(4, 1): 6, A = {(2, 6): [(3, 6)], (3, 3): [(3, 4)], (3, 4): [(3, 3), (3, 5)], (3, 5): [(4, 5), (3, 4), (3, 6)], (3, 6): [(2, 6), (3, 5)], (4, 5): [(3, 5), (5, 5)], (4, 8): [(5, 8)], (5, 5): [(4, 5), (6, 5)], (5, 7): [(6, 7), (5, 8)], (5, 8): [(4, 8), (5, 7)], (6, 4): [(6, 5)], (6, 5): [(5, 5), (7, 5), (6, 4), (6, 6)], (6, 6): [(6, 5), (6, 7)], (6, 7): [(5, 7), (7, 7), (6, 6)], (7, 5): [(6, 5), (8, 5)], (7, 7): [(6, 7), (8, 7), (7, 8)], (7, 8): [(7, 7)], (8, 5): [(7, 5)], (8, 7): [(7, 7)]}
(1, 3): 4, A_b = {(3, 6): [(2, 6), (3, 5)], (3, 4): [(3, 3), (3, 5)], (3, 3): [(3, 4)], (3, 5): [(3, 4), (3, 6), (4, 5)], (4, 5): [(3, 5), (5, 5)], (2, 6): [(3, 6)], (5, 5): [(4, 5), (6, 5)], (5, 8): [(4, 8), (5, 7)], (6, 5): [(5, 5), (6, 4), (6, 6), (7, 5)], (6, 7): [(5, 7), (6, 6), (7, 7)], (4, 8): [(5, 8)], (5, 7): [(5, 8), (6, 7)], (7, 5): [(6, 5), (8, 5)], (6, 4): [(6, 5)], (6, 6): [(6, 5), (6, 7)], (7, 7): [(6, 7), (7, 8), (8, 7)], (8, 5): [(7, 5)], (8, 7): [(7, 7)], (7, 8): [(7, 7)]}
(1, 2): 2, w = {((2, 6), (3, 6)): 1, ((3, 3), (3, 4)): 1, ((3, 4), (3, 3)): 1, ((3, 4), (3, 5)): 1, ((3, 5), (4, 5)): 1, ((3, 5), (3, 4)): 1, ((3, 5), (3, 6)): 1, ((3, 6), (2, 6)): 1, ((3, 6), (3, 5)): 1, ((4, 5), (3, 5)): 1, ((4, 5), (5, 5)): 1, ((4, 8), (5, 8)): 1, ((5, 5), (4, 5)): 1, ((5, 5), (6, 5)): 1, ((5, 7), (6, 7)): 1, ((5, 7), (5, 8)): 1, ((5, 8), (4, 8)): 1, ((5, 8), (5, 7)): 1, ((6, 4), (6, 5)): 1, ((6, 5), (5, 5)): 1, ((6, 5), (7, 5)): 1, ((6, 5), (6, 4)): 1, ((6, 5), (6, 6)): 1, ((6, 6), (6, 5)): 1, ((6, 6), (6, 7)): 1, ((6, 7), (5, 7)): 1, ((6, 7), (7, 7)): 1, ((6, 7), (6, 6)): 1, ((7, 5), (6, 5)): 1, ((7, 5), (8, 5)): 1, ((7, 7), (6, 7)): 1, ((7, 7), (8, 7)): 1, ((7, 7), (7, 8)): 1, ((7, 8), (7, 7)): 1, ((8, 5), (7, 5)): 1, ((8, 7), (7, 7)): 1}
(2, 4): 5, print(a_star_algorithm((3, 3), (4, 8), N, A, w, heuristic_cost_manhattan))
(3, 4): 1,
(5, 3): 1
}
print(a_star_algorithm(g, 7, 10, heuristic_cost))
print(a_star_algorithm(g2, 1, 4, heuristic_cost, is_directed=True))
print(a_star_algorithm(g2, 1, 5, heuristic_cost, is_directed=True))

View File

@ -1,191 +1,135 @@
def heuristic_cost(start, goal, graph): import fibheap
import math
def heuristic_cost(node1, node2):
return 0 return 0
def bidirectional_algorithm(graph, start, goal, h=heuristic_cost, is_directed=False): def heuristic_cost_manhattan(node1, node2):
def return_path_and_weight_front(c_f, c, s): part1 = (node1[0]-node2[0])**2
current_node = c_f[c] part1 = part1
shortest_path = [c, current_node] part2 = (node1[1]-node2[1])**2
while current_node != s: return math.sqrt(part1 + part2)
current_node = c_f[current_node]
shortest_path.append(current_node)
weight = 0
for k in range(len(shortest_path) - 1):
if not is_directed:
if shortest_path[k] > shortest_path[k+1]:
weight += graph[(shortest_path[k], shortest_path[k+1])]
else:
weight += graph[(shortest_path[k + 1], shortest_path[k])]
else:
weight += graph[(shortest_path[k + 1], shortest_path[k])]
return shortest_path, weight
def return_path_and_weight_back(c_f, c, s):
current_node = c_f[c]
shortest_path = [c, current_node]
while current_node != s:
current_node = c_f[current_node]
shortest_path.append(current_node)
weight = 0
shortest_path.reverse()
for k in range(len(shortest_path) - 1):
if not is_directed:
if shortest_path[k] > shortest_path[k+1]:
weight += graph[(shortest_path[k], shortest_path[k+1])]
else:
weight += graph[(shortest_path[k + 1], shortest_path[k])]
else:
weight += graph[(shortest_path[k + 1], shortest_path[k])]
return shortest_path, weight
def return_path_and_weight_front_meet_back(c_f_f, c_f_b, c_f, s, g): def bidirectional_algorithm(s, t, N, A, A_b, w, h):
shortest_path_front, weight_front = return_path_and_weight_front(c_f_f, c_f, s) if s == t:
shortest_path_back, weight_back = return_path_and_weight_back(c_f_b, c_f, g) return [s], 0
shortest_path_back.reverse()
shortest_path_front.reverse()
return shortest_path_front + shortest_path_back[1:], weight_front + weight_back
def return_path_and_weight_back_meet_front(c_f_f, c_f_b, c_b, s, g): H_f = fibheap.makefheap()
shortest_path_front, weight_front = return_path_and_weight_front(c_f_f, c_b, s) H_b = fibheap.makefheap()
shortest_path_back, weight_back = return_path_and_weight_back(c_f_b, c_b, g)
shortest_path_back.reverse()
shortest_path_front.reverse()
return shortest_path_front + shortest_path_back[1:], weight_front + weight_back
point_set_front = dict() d_f = {}
point_set_back = dict() d_b = {}
for arc in g.keys(): heap_node_connection_f = {}
point_set_front[arc[0]] = [] heap_node_connection_b = {}
point_set_front[arc[1]] = [] pred_f = {}
point_set_back[arc[0]] = [] pred_b = {}
point_set_back[arc[1]] = [] f_f = {}
f_b = {}
perm_f = {}
perm_b = {}
for arc in graph.keys(): for i in N:
point_set_front[arc[0]].append(arc[1]) d_f[i] = float('inf')
if not is_directed: d_b[i] = float('inf')
point_set_back[arc[1]].append(arc[0]) perm_f[i] = False
point_set_front[arc[1]].append(arc[0]) perm_b[i] = False
point_set_back[arc[0]].append(arc[1])
d_f[s] = 0
d_b[t] = 0
f_f[s] = d_f[s] + h(s, t)
f_b[t] = d_b[t] + h(t, s)
pred_f[s] = None
pred_b[t] = None
heap_node_connection_f[s] = fibheap.fheappush(H_f, 0, s)
heap_node_connection_b[s] = fibheap.fheappush(H_b, 0, t)
ending_node = s
success = False
while H_f.num_nodes > 0 and H_b.num_nodes > 0:
i_f = fibheap.fheappop(H_f)[1]
i_b = fibheap.fheappop(H_b)[1]
if f_f[i_f] <= f_b[i_b]:
perm_f[i_f] = True
heap_node_connection_b[i_b] = fibheap.fheappush(H_b, f_b[i_b], i_b)
if perm_b[i_f] or i_f == t:
ending_node = i_f
success = True
break
for j in A[i_f]:
path_sum = d_f[i_f] + w[(i_f, j)]
if d_f[j] > path_sum:
pred_f[j] = i_f
f_f[j] = path_sum + h(j, t)
if d_f[j] == float('inf'):
d_f[j] = path_sum
heap_node_connection_f[j] = fibheap.fheappush(H_f, f_f[j], j)
else:
d_f[j] = path_sum
H_f.decrease_key(heap_node_connection_f[j], f_f[j])
else: else:
point_set_back[arc[1]].append(arc[0]) perm_f[i_f] = True
heap_node_connection_f[i_f] = fibheap.fheappush(H_f, f_f[i_f], i_f)
open_set_front = set() if perm_f[i_b] or i_b == s:
open_set_front.add(start) ending_node = i_b
success = True
open_set_back = set() break
open_set_back.add(goal) for j in A_b[i_b]:
path_sum = d_b[i_b] + w[(j, i_b)]
came_from_front = {} if d_b[j] > path_sum:
came_from_back = {} pred_b[j] = i_b
f_b[j] = path_sum + h(j, s)
g_score_front = {k: float('inf') for k in point_set_front.keys()} if d_b[j] == float('inf'):
g_score_front[start] = 0 d_b[j] = path_sum
heap_node_connection_b[j] = fibheap.fheappush(H_b, f_b[j], j)
g_score_back = {k: float('inf') for k in point_set_back.keys()} else:
g_score_back[goal] = 0 d_b[j] = path_sum
H_b.decrease_key(heap_node_connection_b[j], f_b[j])
f_score_front = {k: float('inf') for k in point_set_front.keys()} if success:
f_score_front[start] = h(start, goal, graph) if ending_node == t:
path = [t]
f_score_back = {k: float('inf') for k in point_set_back.keys()} current_node = ending_node
f_score_back[goal] = h(goal, start, graph) while pred_f[current_node] is not None:
path.append(pred_f[current_node])
while len(open_set_front) > 0 and len(open_set_back) > 0: current_node = pred_f[current_node]
current_front = list(open_set_front)[0] path.reverse()
current_back = list(open_set_back)[0] return path, d_f[t]
elif ending_node == s:
for k in open_set_front: path = [s]
if f_score_front[k] < f_score_front[current_front]: current_node = s
current_front = k while pred_b[current_node] is not None:
path.append(pred_b[current_node])
for k in open_set_back: current_node = pred_b[current_node]
if f_score_back[k] < f_score_back[current_back]: return path, d_b[s]
current_back = k else:
path1 = [ending_node]
if current_front == goal: current_node = ending_node
return return_path_and_weight_front(came_from_front, current_front, start) while pred_f[current_node] is not None:
path1.append(pred_f[current_node])
if current_back == start: current_node = pred_f[current_node]
return return_path_and_weight_back(came_from_back, current_back, goal) path1.reverse()
path2 = []
if current_front in came_from_back.keys() and current_back in came_from_front.keys(): current_node = ending_node
path1, weight1 = return_path_and_weight_front_meet_back(came_from_front, came_from_back, current_front, while pred_b[current_node] is not None:
start, goal) path2.append(pred_b[current_node])
path2, weight2 = return_path_and_weight_back_meet_front(came_from_front, came_from_back, current_back, current_node = pred_b[current_node]
start, goal) return path1 + path2, d_f[ending_node] + d_b[ending_node]
if weight1 < weight2: return None, None
return path1, weight1
return path2, weight2
if current_front in came_from_back.keys():
return return_path_and_weight_front_meet_back(came_from_front, came_from_back, current_front, start, goal)
if current_back in came_from_front.keys():
return return_path_and_weight_back_meet_front(came_from_front, came_from_back, current_back, start, goal)
open_set_front.remove(current_front)
open_set_back.remove(current_back)
for neighbor in point_set_front[current_front]:
tentative_g_score = g_score_front[current_front]
if not is_directed:
if current_front > neighbor:
tentative_g_score += graph[(current_front, neighbor)]
else:
tentative_g_score += graph[(neighbor, current_front)]
else:
tentative_g_score += graph[(current_front, neighbor)]
if tentative_g_score < g_score_front[neighbor]:
came_from_front[neighbor] = current_front
g_score_front[neighbor] = tentative_g_score
f_score_front[neighbor] = g_score_front[neighbor] + h(neighbor, goal, graph)
if neighbor not in open_set_front:
open_set_front.add(neighbor)
for neighbor in point_set_back[current_back]:
tentative_g_score = g_score_back[current_back]
if not is_directed:
if current_back > neighbor:
tentative_g_score += graph[(current_back, neighbor)]
else:
tentative_g_score += graph[(neighbor, current_back)]
else:
tentative_g_score += graph[(neighbor, current_back)]
if tentative_g_score < g_score_back[neighbor]:
came_from_back[neighbor] = current_back
g_score_back[neighbor] = tentative_g_score
f_score_back[neighbor] = g_score_back[neighbor] + h(neighbor, goal, graph)
if neighbor not in open_set_back:
open_set_back.add(neighbor)
if __name__ == "__main__": if __name__ == "__main__":
g = { N = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
(2, 1): 3, A = {1: [2, 8, 6], 2: [1, 3, 5], 8: [1, 4], 3: [2], 5: [2, 7, 9, 10], 4: [6, 7, 8], 6: [4, 1], 7: [4, 5], 9: [5], 10: [5]}
(3, 2): 2, A_b = {2: [1, 3, 5], 1: [2, 8, 6], 8: [1, 4], 3: [2], 5: [2, 7, 9, 10], 6: [4, 1], 4: [6, 7, 8], 7: [4, 5], 9: [5], 10: [5]}
(5, 3): 1, w = {(1, 2): 84, (2, 1): 84, (1, 8): 52, (8, 1): 52, (2, 3): 4, (3, 2): 4, (2, 5): 39, (5, 2): 39, (4, 6): 74, (6, 4): 74, (4, 7): 81, (7, 4): 81, (5, 7): 45, (7, 5): 45, (5, 9): 66, (9, 5): 66, (5, 10): 19, (10, 5): 19, (4, 8): 87, (8, 4): 87, (1, 6): 4, (6, 1): 4}
(9, 5): 5, print(bidirectional_algorithm(1, 10, N, A, A_b, w, heuristic_cost))
(10, 9): 4,
(9, 4): 3,
(4, 1): 4,
(7, 1): 6,
(3, 1): 4,
(6, 2): 3,
(8, 6): 8,
(8, 3): 2,
(9, 1): 8
}
g2 = { N = {(3, 4), (5, 7), (7, 7), (6, 5), (4, 5), (3, 3), (4, 8), (3, 6), (8, 5), (6, 4), (6, 7), (3, 5), (5, 5), (5, 8), (8, 7), (2, 6), (6, 6), (7, 5), (7, 8)}
(4, 1): 6, A = {(2, 6): [(3, 6)], (3, 3): [(3, 4)], (3, 4): [(3, 3), (3, 5)], (3, 5): [(4, 5), (3, 4), (3, 6)], (3, 6): [(2, 6), (3, 5)], (4, 5): [(3, 5), (5, 5)], (4, 8): [(5, 8)], (5, 5): [(4, 5), (6, 5)], (5, 7): [(6, 7), (5, 8)], (5, 8): [(4, 8), (5, 7)], (6, 4): [(6, 5)], (6, 5): [(5, 5), (7, 5), (6, 4), (6, 6)], (6, 6): [(6, 5), (6, 7)], (6, 7): [(5, 7), (7, 7), (6, 6)], (7, 5): [(6, 5), (8, 5)], (7, 7): [(6, 7), (8, 7), (7, 8)], (7, 8): [(7, 7)], (8, 5): [(7, 5)], (8, 7): [(7, 7)]}
(1, 3): 4, A_b = {(3, 6): [(2, 6), (3, 5)], (3, 4): [(3, 3), (3, 5)], (3, 3): [(3, 4)], (3, 5): [(3, 4), (3, 6), (4, 5)], (4, 5): [(3, 5), (5, 5)], (2, 6): [(3, 6)], (5, 5): [(4, 5), (6, 5)], (5, 8): [(4, 8), (5, 7)], (6, 5): [(5, 5), (6, 4), (6, 6), (7, 5)], (6, 7): [(5, 7), (6, 6), (7, 7)], (4, 8): [(5, 8)], (5, 7): [(5, 8), (6, 7)], (7, 5): [(6, 5), (8, 5)], (6, 4): [(6, 5)], (6, 6): [(6, 5), (6, 7)], (7, 7): [(6, 7), (7, 8), (8, 7)], (8, 5): [(7, 5)], (8, 7): [(7, 7)], (7, 8): [(7, 7)]}
(1, 2): 2, w = {((2, 6), (3, 6)): 1, ((3, 3), (3, 4)): 1, ((3, 4), (3, 3)): 1, ((3, 4), (3, 5)): 1, ((3, 5), (4, 5)): 1, ((3, 5), (3, 4)): 1, ((3, 5), (3, 6)): 1, ((3, 6), (2, 6)): 1, ((3, 6), (3, 5)): 1, ((4, 5), (3, 5)): 1, ((4, 5), (5, 5)): 1, ((4, 8), (5, 8)): 1, ((5, 5), (4, 5)): 1, ((5, 5), (6, 5)): 1, ((5, 7), (6, 7)): 1, ((5, 7), (5, 8)): 1, ((5, 8), (4, 8)): 1, ((5, 8), (5, 7)): 1, ((6, 4), (6, 5)): 1, ((6, 5), (5, 5)): 1, ((6, 5), (7, 5)): 1, ((6, 5), (6, 4)): 1, ((6, 5), (6, 6)): 1, ((6, 6), (6, 5)): 1, ((6, 6), (6, 7)): 1, ((6, 7), (5, 7)): 1, ((6, 7), (7, 7)): 1, ((6, 7), (6, 6)): 1, ((7, 5), (6, 5)): 1, ((7, 5), (8, 5)): 1, ((7, 7), (6, 7)): 1, ((7, 7), (8, 7)): 1, ((7, 7), (7, 8)): 1, ((7, 8), (7, 7)): 1, ((8, 5), (7, 5)): 1, ((8, 7), (7, 7)): 1}
(2, 4): 5, print(bidirectional_algorithm((3, 3), (4, 8), N, A, A_b, w, heuristic_cost_manhattan))
(3, 4): 1,
(5, 3): 1
}
# print(bidirectional_algorithm(g, 7, 10, heuristic_cost))
# print(bidirectional_algorithm(g2, 1, 4, heuristic_cost, is_directed=True))
# print(bidirectional_algorithm(g2, 1, 5, heuristic_cost, is_directed=True))

View File

@ -1,119 +1,64 @@
import heapq as heap
import fibheap import fibheap
# function which takes graph, vertex set, start and goal, uses djikstra algorithm to establish shortest paths from start def dijkstra_algorithm(s, t, N, A, w):
# every other vertex in graph and returns shortest path between start and goal """
def dijkstra_algorithm(graph, start, goal, is_directed=False):
# dictionary which will store for every vertex it's distance to start
dist = dict()
# dictionary which keeps if vertex was already popped from queue :param graph:
visited = dict() :param start:
:param goal:
:param is_directed:
:return:
"""
if s == t:
return [s], 0
# dictionary which keeps for every vertex which other vertex is previous on the shortest path from start H = fibheap.makefheap()
prev = dict() d = {}
heap_node_connection = {}
pred = {}
# list which is used to keep priority queue with vertexes to be explored by the algorithm for i in N:
queue = [] d[i] = float('inf')
d[s] = 0
# dictionary for keeping neighbors of vertexes. pred[s] = None
point_set = dict() heap_node_connection[s] = fibheap.fheappush(H, 0, s)
for arc in graph.keys(): success = False
point_set[arc[0]] = [] while H.num_nodes > 0:
point_set[arc[1]] = [] i = fibheap.fheappop(H)[1]
if i == t:
# creating dictionary which for every vertex keeps all it's neighbors success = True
for arc in graph.keys(): break
point_set[arc[0]].append(arc[1]) for j in A[i]:
if not is_directed: path_sum = d[i] + w[(i, j)]
point_set[arc[1]].append(arc[0]) if d[j] > path_sum:
pred[j] = i
# initialization of needed lists if d[j] == float('inf'):
for vertex in point_set: d[j] = path_sum
# setting distance of every vertex from the starting vertex to infinity heap_node_connection[j] = fibheap.fheappush(H, path_sum, j)
dist[vertex] = float('inf')
# setting previous vertex in currently found shortest path for every vertex to None
prev[vertex] = None
# setting flag for every vertex keeping track if it was already visited my the algorithm
visited[vertex] = False
heap_node_connection = dict()
# pushing start vertex to priority queue
node_heap = fibheap.makefheap()
heap_node_connection[start] = fibheap.fheappush(node_heap, 0, start)
# setting distance to start for start vertex to 0
dist[start] = 0
# setting start vertex not to be added to priority queue again
visited[start] = True
# main loop
while node_heap.num_nodes > 0:
# getting first vertex from the priority queue and saving it in current variable
current = fibheap.fheappop(node_heap)
# current = heap.heappop(queue)
# iterating trough all neighbors of the current vertex
for neighbor in point_set[current[1]]:
# initializing potential distance to be replaced with the current neighbors
new_dist = 0
#
if not is_directed:
if neighbor > current[1]:
new_dist = dist[current[1]] + graph[(neighbor, current[1])]
else: else:
new_dist = dist[current[1]] + graph[(current[1], neighbor)] d[j] = path_sum
else: H.decrease_key(heap_node_connection[j], path_sum)
new_dist = dist[current[1]] + graph[(current[1], neighbor)] if success:
if new_dist < dist[neighbor]: path = [t]
if dist[neighbor] == float('inf'): current_node = t
dist[neighbor] = new_dist while pred[current_node] is not None:
prev[neighbor] = current[1] path.append(pred[current_node])
heap_node_connection[neighbor] = fibheap.fheappush(node_heap, new_dist, neighbor) current_node = pred[current_node]
# heap.heappush(queue, (new_dist, neighbor)) path.reverse()
else: return path, d[t]
dist[neighbor] = new_dist return None, None
prev[neighbor] = current[1]
node_heap.decrease_key(heap_node_connection[neighbor], new_dist)
# for k in range(len(queue)):
# if queue[k][1] == neighbor:
# queue[k] = (new_dist, neighbor)
# heap.heapify(queue)
temp = goal
shortest_path = [goal]
while prev[temp] is not None:
shortest_path.append(prev[temp])
temp = prev[temp]
shortest_path.reverse()
return shortest_path, dist[goal]
if __name__ == "__main__": if __name__ == "__main__":
g1 = { N = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
(2, 1): 3, A = {1: [2, 8, 6], 2: [1, 3, 5], 8: [1, 4], 3: [2], 5: [2, 7, 9, 10], 4: [6, 7, 8], 6: [4, 1], 7: [4, 5], 9: [5], 10: [5]}
(3, 2): 2, A_b = {2: [1, 3, 5], 1: [2, 8, 6], 8: [1, 4], 3: [2], 5: [2, 7, 9, 10], 6: [4, 1], 4: [6, 7, 8], 7: [4, 5], 9: [5], 10: [5]}
(5, 3): 1, w = {(1, 2): 84, (2, 1): 84, (1, 8): 52, (8, 1): 52, (2, 3): 4, (3, 2): 4, (2, 5): 39, (5, 2): 39, (4, 6): 74, (6, 4): 74, (4, 7): 81, (7, 4): 81, (5, 7): 45, (7, 5): 45, (5, 9): 66, (9, 5): 66, (5, 10): 19, (10, 5): 19, (4, 8): 87, (8, 4): 87, (1, 6): 4, (6, 1): 4}
(9, 5): 5, print(dijkstra_algorithm(1, 10, N, A, w))
(10, 9): 4,
(9, 4): 3,
(4, 1): 4,
(7, 1): 6,
(3, 1): 4,
(6, 2): 3,
(8, 6): 8,
(8, 3): 2,
(9, 1): 8
}
g2 = { N = {(3, 4), (5, 7), (7, 7), (6, 5), (4, 5), (3, 3), (4, 8), (3, 6), (8, 5), (6, 4), (6, 7), (3, 5), (5, 5), (5, 8), (8, 7), (2, 6), (6, 6), (7, 5), (7, 8)}
(4, 1): 6, A = {(2, 6): [(3, 6)], (3, 3): [(3, 4)], (3, 4): [(3, 3), (3, 5)], (3, 5): [(4, 5), (3, 4), (3, 6)], (3, 6): [(2, 6), (3, 5)], (4, 5): [(3, 5), (5, 5)], (4, 8): [(5, 8)], (5, 5): [(4, 5), (6, 5)], (5, 7): [(6, 7), (5, 8)], (5, 8): [(4, 8), (5, 7)], (6, 4): [(6, 5)], (6, 5): [(5, 5), (7, 5), (6, 4), (6, 6)], (6, 6): [(6, 5), (6, 7)], (6, 7): [(5, 7), (7, 7), (6, 6)], (7, 5): [(6, 5), (8, 5)], (7, 7): [(6, 7), (8, 7), (7, 8)], (7, 8): [(7, 7)], (8, 5): [(7, 5)], (8, 7): [(7, 7)]}
(1, 3): 4, A_b = {(3, 6): [(2, 6), (3, 5)], (3, 4): [(3, 3), (3, 5)], (3, 3): [(3, 4)], (3, 5): [(3, 4), (3, 6), (4, 5)], (4, 5): [(3, 5), (5, 5)], (2, 6): [(3, 6)], (5, 5): [(4, 5), (6, 5)], (5, 8): [(4, 8), (5, 7)], (6, 5): [(5, 5), (6, 4), (6, 6), (7, 5)], (6, 7): [(5, 7), (6, 6), (7, 7)], (4, 8): [(5, 8)], (5, 7): [(5, 8), (6, 7)], (7, 5): [(6, 5), (8, 5)], (6, 4): [(6, 5)], (6, 6): [(6, 5), (6, 7)], (7, 7): [(6, 7), (7, 8), (8, 7)], (8, 5): [(7, 5)], (8, 7): [(7, 7)], (7, 8): [(7, 7)]}
(1, 2): 2, w = {((2, 6), (3, 6)): 1, ((3, 3), (3, 4)): 1, ((3, 4), (3, 3)): 1, ((3, 4), (3, 5)): 1, ((3, 5), (4, 5)): 1, ((3, 5), (3, 4)): 1, ((3, 5), (3, 6)): 1, ((3, 6), (2, 6)): 1, ((3, 6), (3, 5)): 1, ((4, 5), (3, 5)): 1, ((4, 5), (5, 5)): 1, ((4, 8), (5, 8)): 1, ((5, 5), (4, 5)): 1, ((5, 5), (6, 5)): 1, ((5, 7), (6, 7)): 1, ((5, 7), (5, 8)): 1, ((5, 8), (4, 8)): 1, ((5, 8), (5, 7)): 1, ((6, 4), (6, 5)): 1, ((6, 5), (5, 5)): 1, ((6, 5), (7, 5)): 1, ((6, 5), (6, 4)): 1, ((6, 5), (6, 6)): 1, ((6, 6), (6, 5)): 1, ((6, 6), (6, 7)): 1, ((6, 7), (5, 7)): 1, ((6, 7), (7, 7)): 1, ((6, 7), (6, 6)): 1, ((7, 5), (6, 5)): 1, ((7, 5), (8, 5)): 1, ((7, 7), (6, 7)): 1, ((7, 7), (8, 7)): 1, ((7, 7), (7, 8)): 1, ((7, 8), (7, 7)): 1, ((8, 5), (7, 5)): 1, ((8, 7), (7, 7)): 1}
(2, 4): 5, print(dijkstra_algorithm((3, 3), (4, 8), N, A, w))
(3, 4): 1,
(5, 3): 1
}
print(dijkstra_algorithm(g1, 7, 10))
print(dijkstra_algorithm(g2, 1, 4, is_directed=True))
print(dijkstra_algorithm(g2, 1, 5, is_directed=True))

118
dataset/generate_graph.py Normal file
View File

@ -0,0 +1,118 @@
import random
def sort_edges(edges, edge):
if edge[0] > edge[1]:
temp = edge[0]
edge[0] = edge[1]
edge[1] = temp
index = 0
for i in edges:
if edge[0] < i[0]:
break
elif edge[0] == i[0] and edge[1] < i[1]:
break
else:
index += 1
edges.insert(index, edge)
def generate_tree_from_prufer_code(code):
L1 = code[:]
L2 = []
edges = []
nodes = set()
for i in range(len(code)+2):
L2.append(i+1)
nodes.add(i+1)
for k in range(len(L1)):
current_node = L2[0]
counter = 1
while L1.count(current_node) > 0:
current_node = L2[counter]
counter += 1
sort_edges(edges, [code[k], current_node])
L1.remove(code[k])
L2.remove(current_node)
sort_edges(edges, [L2[0], L2[1]])
return edges
def generate_prufers_code(n: int):
code = []
for i in range(n-2):
code.append(random.randint(1, n))
return code
def generate_random_graph(n: int, log=False):
code = generate_prufers_code(n)
edges = generate_tree_from_prufer_code(code)
number_of_edges_to_add = random.randint(n//4, int(n/3))
if log:
print("number of edges to add:", number_of_edges_to_add)
counter = 0
while counter < number_of_edges_to_add:
node1 = random.randint(1, n)
node2 = random.randint(1, n)
while node1 == node2:
node2 = random.randint(1, n)
if node1 < node2:
if [node1, node2] not in edges:
edges.append([node1, node2])
counter += 1
else:
if [node2, node1] not in edges:
edges.append([node2, node1])
counter += 1
return edges
def write_graph_to_file(graph, filename, path="graphs/"):
with open(path + filename, 'w') as file:
for edge in graph:
weight = random.randint(1, 100)
file.write(str(edge[0]) + " " + str(edge[1]) + " " + str(weight) + "\n")
file.write(str(edge[1]) + " " + str(edge[0]) + " " + str(weight) + "\n")
def read_graph_from_file(filename, path="graphs/"):
N = set()
A = {}
A_b = {}
w = {}
with open(path + filename, 'r') as file:
line = file.readline()
while line != '':
split = line.strip('\n').split(" ")
first_node = int(split[0])
second_node = int(split[1])
N.add(first_node)
N.add(second_node)
if first_node not in A.keys():
A[first_node] = [second_node]
else:
A[first_node].append(second_node)
if second_node not in A_b.keys():
A_b[second_node] = [first_node]
else:
A_b[second_node].append(first_node)
w[(first_node, second_node)] = int(split[2])
line = file.readline()
return N, A, A_b, w
if __name__ == '__main__':
for i in range(1, 11):
n = random.randint(3000, 6000)
print("generating graph:", i, "of", 10, "with", n, "nodes")
g = generate_random_graph(n, log=True)
f = "graph" + str(i)
write_graph_to_file(g, f)

162
dataset/generate_grid.py Normal file
View File

@ -0,0 +1,162 @@
import random as rand
def generate_grid(height: int, width: int, fill_percent: int = 70):
"""
Generates grid with a simple maze. Path is signed as 'p' and walls as 'w'. It always has walls surrounding it.
:param height: height of the grid.
:param width: width of the grid.
:param fill_percent: percentage of walls in the maze (not counting surrounding walls).
:return:
"""
grid = []
for i in range(height):
grid.append([])
for j in range(width):
grid[i].append('w')
path_percent = (100. - float(fill_percent)) / 100.
grid_size = float((height-2) * (width-2))
paths_number = int(path_percent * grid_size)
start_point_y = height // 2
start_point_x = width // 2
grid[start_point_y][start_point_x] = 'p'
set_paths = 1
path_list = [(start_point_y, start_point_x)]
while set_paths < paths_number:
chosen_position = rand.randint(0, len(path_list)-1)
random_growth = rand.randint(0, 3)
if random_growth == 0:
if path_list[chosen_position][0]+1 == height-1:
continue
else:
new_y = path_list[chosen_position][0] + 1
new_x = path_list[chosen_position][1]
if grid[new_y][new_x] == 'w':
if grid[new_y][new_x-1] == 'p' or grid[new_y][new_x+1] == 'p' or grid[new_y+1][new_x] == 'p':
if rand.randint(0, 100) < 1:
grid[new_y][new_x] = 'p'
set_paths += 1
path_list.append((new_y, new_x))
else:
grid[new_y][new_x] = 'p'
set_paths += 1
path_list.append((new_y, new_x))
elif random_growth == 1:
if path_list[chosen_position][1]-1 == 0:
continue
else:
new_y = path_list[chosen_position][0]
new_x = path_list[chosen_position][1] - 1
if grid[new_y][new_x] == 'w':
if grid[new_y][new_x-1] == 'p' or grid[new_y-1][new_x] == 'p' or grid[new_y+1][new_x] == 'p':
if rand.randint(0, 100) < 1:
grid[new_y][new_x] = 'p'
set_paths += 1
path_list.append((new_y, new_x))
else:
grid[new_y][new_x] = 'p'
set_paths += 1
path_list.append((new_y, new_x))
elif random_growth == 2:
if path_list[chosen_position][0]-1 == 0:
continue
else:
new_y = path_list[chosen_position][0]-1
new_x = path_list[chosen_position][1]
if grid[new_y][new_x] == 'w':
if grid[new_y][new_x+1] == 'p' or grid[new_y][new_x-1] == 'p' or grid[new_y-1][new_x] == 'p':
if rand.randint(0, 100) < 1:
grid[new_y][new_x] = 'p'
set_paths += 1
path_list.append((new_y, new_x))
else:
grid[new_y][new_x] = 'p'
set_paths += 1
path_list.append((new_y, new_x))
elif random_growth == 3:
if path_list[chosen_position][1] + 1 == width-1:
continue
else:
new_y = path_list[chosen_position][0]
new_x = path_list[chosen_position][1] + 1
if grid[new_y][new_x] == 'w':
if grid[new_y][new_x+1] == 'p' or grid[new_y-1][new_x] == 'p' or grid[new_y+1][new_x] == 'p':
if rand.randint(0, 100) < 1:
grid[new_y][new_x] = 'p'
set_paths += 1
path_list.append((new_y, new_x))
else:
grid[new_y][new_x] = 'p'
set_paths += 1
path_list.append((new_y, new_x))
return grid
def write_grid_as_graph_to_file(grid, filename, path="grids/"):
"""
Writes generated grid to file as a graph with weights
:param grid: grid generated by function generate_grid
:param filename: name of the file to save the graph to
:param path: path to save the file in
:return: None
"""
with open(path + filename, 'w') as file:
for i in range(1, len(grid)-1):
for j in range(1, len(grid[i])-1):
if grid[i][j] == 'p':
if grid[i-1][j] == 'p':
file.write(str(i) + " " + str(j) + "," + str(i-1) + " " + str(j) + "," + "1" + "\n")
if grid[i+1][j] == 'p':
file.write(str(i) + " " + str(j) + "," + str(i+1) + " " + str(j) + "," + "1" + "\n")
if grid[i][j-1] == 'p':
file.write(str(i) + " " + str(j) + "," + str(i) + " " + str(j-1) + "," + "1" + "\n")
if grid[i][j+1] == 'p':
file.write(str(i) + " " + str(j) + "," + str(i) + " " + str(j+1) + "," + "1" + "\n")
def read_grid_graph_from_file(filename, path="grids/"):
N = set()
A = {}
A_b = {}
w = {}
with open(path + filename, "r") as file:
line = file.readline()
while line != '':
split = line.strip("\n").split(",")
fist_node_str_list = split[0].split(" ")
second_node_str_list = split[1].split(" ")
weight = int(split[2])
first_node = (int(fist_node_str_list[0]), int(fist_node_str_list[1]))
second_node = (int(second_node_str_list[0]), int(second_node_str_list[1]))
N.add(first_node)
N.add(second_node)
if first_node not in A.keys():
A[first_node] = [second_node]
else:
A[first_node].append(second_node)
if second_node not in A_b.keys():
A_b[second_node] = [first_node]
else:
A_b[second_node].append(first_node)
w[(first_node, second_node)] = weight
line = file.readline()
return N, A, A_b, w
if __name__ == "__main__":
for i in range(1, 11):
print("generating graph:", i, "of", 10)
f = "grid" + str(i)
g = generate_grid(rand.randint(202, 502), rand.randint(202, 502))
write_grid_as_graph_to_file(g, f)

13536
dataset/graphs/graph1 Normal file

File diff suppressed because it is too large Load Diff

10282
dataset/graphs/graph10 Normal file

File diff suppressed because it is too large Load Diff

8320
dataset/graphs/graph2 Normal file

File diff suppressed because it is too large Load Diff

12404
dataset/graphs/graph3 Normal file

File diff suppressed because it is too large Load Diff

14570
dataset/graphs/graph4 Normal file

File diff suppressed because it is too large Load Diff

8824
dataset/graphs/graph5 Normal file

File diff suppressed because it is too large Load Diff

10980
dataset/graphs/graph6 Normal file

File diff suppressed because it is too large Load Diff

8566
dataset/graphs/graph7 Normal file

File diff suppressed because it is too large Load Diff

12582
dataset/graphs/graph8 Normal file

File diff suppressed because it is too large Load Diff

15104
dataset/graphs/graph9 Normal file

File diff suppressed because it is too large Load Diff

147908
dataset/grids/grid1 Normal file

File diff suppressed because it is too large Load Diff

184054
dataset/grids/grid10 Normal file

File diff suppressed because it is too large Load Diff

76278
dataset/grids/grid2 Normal file

File diff suppressed because it is too large Load Diff

128018
dataset/grids/grid3 Normal file

File diff suppressed because it is too large Load Diff

141502
dataset/grids/grid4 Normal file

File diff suppressed because it is too large Load Diff

234902
dataset/grids/grid5 Normal file

File diff suppressed because it is too large Load Diff

103124
dataset/grids/grid6 Normal file

File diff suppressed because it is too large Load Diff

167940
dataset/grids/grid7 Normal file

File diff suppressed because it is too large Load Diff

76494
dataset/grids/grid8 Normal file

File diff suppressed because it is too large Load Diff

74702
dataset/grids/grid9 Normal file

File diff suppressed because it is too large Load Diff

198
main.py
View File

@ -1,15 +1,195 @@
import tools.file_service as op_file
import algorithms.dijkstra as dijkstra import algorithms.dijkstra as dijkstra
import algorithms.a_star as a_star import algorithms.a_star as a_star
import algorithms.bidirectional as bidirectional import algorithms.bidirectional as bidirectional
import dataset.generate_graph as gen_graph
import dataset.generate_grid as gen_grid
import time
import tracemalloc
import os
import random as rand
if __name__ == '__main__': if __name__ == '__main__':
g = op_file.read_graph_from_file("dataset/deezer_clean_data/HR_edges_with_weight.csv", has_weight=True) current_graph = []
v = dict() nodes_chosen = []
for i in g.keys(): dijkstra_time, dijkstra_memory, dijkstra_weight = [], [], []
v[i[0]] = [] a_star_time, a_star_memory, a_star_weight = [], [], []
v[i[1]] = [] bidirectional_time, bidirectional_memory, bidirectional_weight = [], [], []
for i in range(1, len(os.listdir('dataset/graphs')) + 1):
filename = "graph" + str(i)
print(filename)
N, A, A_b, w = gen_graph.read_graph_from_file(filename, path="dataset/graphs/")
for j in range(3):
current_graph.append(filename)
start_node_index = rand.randint(0, len(N)-1)
goal_node_index = rand.randint(0, len(N)-1)
while goal_node_index == start_node_index:
goal_node_index = rand.randint(0, len(N) - 1)
start_node = None
goal_node = None
for index, node in enumerate(N):
if index == goal_node_index:
goal_node = node
if index == start_node_index:
start_node = node
if start_node is not None and goal_node is not None:
break
nodes_chosen.append((start_node, goal_node))
startTime = time.time()
tracemalloc.start()
weight = dijkstra.dijkstra_algorithm(start_node, goal_node, N, A, w)[1]
dijkstra_memory.append(tracemalloc.get_traced_memory()[1])
dijkstra_time.append((time.time() - startTime))
dijkstra_weight.append(weight)
tracemalloc.stop()
# print(dijkstra.dijkstra_algorithm(g, v, 0, 4)) startTime = time.time()
# print(a_star.a_star_algorithm(g, v, 0, 4)) tracemalloc.start()
# print(bidirectional.bidirectional_algorithm(g, v, 0, 4)) weight = a_star.a_star_algorithm(start_node, goal_node, N, A, w, a_star.heuristic_cost)[1]
a_star_memory.append(tracemalloc.get_traced_memory()[1])
a_star_time.append((time.time() - startTime))
a_star_weight.append(weight)
tracemalloc.stop()
startTime = time.time()
tracemalloc.start()
weight = bidirectional.bidirectional_algorithm(start_node, goal_node, N, A, A_b, w, a_star.heuristic_cost)[1]
bidirectional_memory.append(tracemalloc.get_traced_memory()[1])
bidirectional_time.append((time.time() - startTime))
bidirectional_weight.append(weight)
tracemalloc.stop()
with open("output/graphs_times.out", "w") as file:
file.write("\\begin{table}[]\n")
file.write("\\begin{tabular}{|l|l|l|l|l|}\n")
file.write("\\hline\n")
file.write("nazwa grafu & (s, t) & Dijkstra & A* & Bi A* \\\\ \\hline\n")
with open("output/graphs_memory.out", "w") as file:
file.write("\\begin{table}[]\n")
file.write("\\begin{tabular}{|l|l|l|l|l|}\n")
file.write("\\hline\n")
file.write("nazwa grafu & (s, t) & Dijkstra & A* & Bi A* \\\\ \\hline\n")
with open("output/graph_weights.out", "w") as file:
file.write("\\begin{table}[]\n")
file.write("\\begin{tabular}{|l|l|l|l|l|}\n")
file.write("\\hline\n")
file.write("nazwa grafu & (s, t) & Dijkstra & A* & Bi A* \\\\ \\hline\n")
with open("output/graphs_times.out", "a") as file:
for j in range(len(dijkstra_time)):
file.write(" " + current_graph[j] + " & " + str(nodes_chosen[j]) + " & " + str(round(dijkstra_time[j], 5))
+ " & " + str(round(a_star_time[j], 5)) + " & " + str(round(bidirectional_time[j], 5)) +
" \\\\ \\hline\n")
file.write("\\end{tabular}\n")
file.write("\\end{table}\n")
with open("output/graphs_memory.out", "a") as file:
for j in range(len(dijkstra_time)):
file.write(" " + current_graph[j] + " & " + str(nodes_chosen[j]) + " & " + str(dijkstra_memory[j])
+ " & " + str(a_star_memory[j]) + " & " + str(bidirectional_memory[j]) + " \\\\ \\hline\n")
file.write("\\end{tabular}\n")
file.write("\\end{table}\n")
with open("output/graph_weights.out", "a") as file:
for j in range(len(dijkstra_time)):
file.write(" " + current_graph[j] + " & " + str(nodes_chosen[j]) + " & " +
str(dijkstra_weight[j]) + " & "+ str(a_star_weight[j]) + " & " +
str(bidirectional_weight[j]) + " \\\\ \\hline\n")
file.write("\\end{tabular}\n")
file.write("\\end{table}\n")
current_graph = []
nodes_chosen = []
dijkstra_time, dijkstra_memory, dijkstra_weight = [], [], []
a_star_time, a_star_memory, a_star_weight = [], [], []
bidirectional_time, bidirectional_memory, bidirectional_weight = [], [], []
for i in range(1, len(os.listdir('dataset/grids')) + 1):
filename = "grid" + str(i)
print(filename)
N, A, A_b, w = gen_grid.read_grid_graph_from_file(filename, path="dataset/grids/")
for j in range(3):
current_graph.append(filename)
start_node_index = rand.randint(0, len(N)-1)
goal_node_index = rand.randint(0, len(N)-1)
while goal_node_index == start_node_index:
goal_node_index = rand.randint(0, len(N) - 1)
start_node = None
goal_node = None
for index, node in enumerate(N):
if index == goal_node_index:
goal_node = node
if index == start_node_index:
start_node = node
if start_node is not None and goal_node is not None:
break
nodes_chosen.append((start_node, goal_node))
startTime = time.time()
tracemalloc.start()
weight = dijkstra.dijkstra_algorithm(start_node, goal_node, N, A, w)[1]
dijkstra_memory.append(tracemalloc.get_traced_memory()[1])
dijkstra_time.append((time.time() - startTime))
dijkstra_weight.append(weight)
tracemalloc.stop()
startTime = time.time()
tracemalloc.start()
weight = a_star.a_star_algorithm(start_node, goal_node, N, A, w, a_star.heuristic_cost_manhattan)[1]
a_star_memory.append(tracemalloc.get_traced_memory()[1])
a_star_time.append((time.time() - startTime))
a_star_weight.append(weight)
tracemalloc.stop()
startTime = time.time()
tracemalloc.start()
weight = bidirectional.bidirectional_algorithm(start_node, goal_node, N, A, A_b, w,
a_star.heuristic_cost_manhattan)[1]
bidirectional_memory.append(tracemalloc.get_traced_memory()[1])
bidirectional_time.append((time.time() - startTime))
bidirectional_weight.append(weight)
tracemalloc.stop()
with open("output/grids_times.out", "w") as file:
file.write("\\begin{table}[]\n")
file.write("\\begin{tabular}{|l|l|l|l|l|}\n")
file.write("\\hline\n")
file.write("nazwa siatki & (s, t) & Dijkstra & A* & Bi A* \\\\ \\hline\n")
with open("output/grids_memory.out", "w") as file:
file.write("\\begin{table}[]\n")
file.write("\\begin{tabular}{|l|l|l|l|l|}\n")
file.write("\\hline\n")
file.write("nazwa siatki & (s, t) & Dijkstra & A* & Bi A* \\\\ \\hline\n")
with open("output/grids_weights.out", "w") as file:
file.write("\\begin{table}[]\n")
file.write("\\begin{tabular}{|l|l|l|l|l|}\n")
file.write("\\hline\n")
file.write("nazwa siatki & (s, t) & Dijkstra & A* & Bi A* \\\\ \\hline\n")
with open("output/grids_times.out", "a") as file:
for j in range(len(dijkstra_time)):
file.write(
" " + current_graph[j] +
" & " + str(nodes_chosen[j]) + " & "
+ str(round(dijkstra_time[j], 5))
+ " & " + str(round(a_star_time[j], 5)) + " & " + str(round(bidirectional_time[j], 5)) +
" \\\\ \\hline\n")
file.write("\\end{tabular}\n")
file.write("\\end{table}\n")
with open("output/grids_memory.out", "a") as file:
for j in range(len(dijkstra_time)):
file.write(" " + current_graph[j] + " & " + str(nodes_chosen[j]) + " & " + str(dijkstra_memory[j])
+ " & " + str(a_star_memory[j]) + " & " + str(bidirectional_memory[j]) + " \\\\ \\hline\n")
file.write("\\end{tabular}\n")
file.write("\\end{table}\n")
with open("output/grids_weights.out", "a") as file:
for j in range(len(dijkstra_time)):
file.write(" " + current_graph[j] + " & " + str(nodes_chosen[j]) + " & " +
str(dijkstra_weight[j]) + " & "+ str(a_star_weight[j]) + " & " +
str(bidirectional_weight[j]) + " \\\\ \\hline\n")
file.write("\\end{tabular}\n")
file.write("\\end{table}\n")

View File

@ -1,32 +0,0 @@
import random as rand
def read_graph_from_file(path, separator=",", read_first_line=False, is_directed=False, has_weight=False):
edges = dict()
with open(path, 'r') as file:
read_line = read_first_line
line = file.readline()
while line != '':
if read_line:
if line[0] != "#":
split = line.strip('\n').split(separator)
node1 = int(split[0])
node2 = int(split[1])
if not is_directed:
if node1 < node2:
node1, node2 = node2, node1
if not has_weight:
edges[(node1, node2)] = 1
else:
edges[(node1, node2)] = int(split[2])
else:
read_line = True
line = file.readline()
return edges
def add_weight_to_file(graph, path, extension, separator=",", weight_scale=(1, 100)):
with open(path + "_with_weight" + extension, 'w') as file:
for key in graph.keys():
file.write(str(key[0]) + separator + str(key[1]) + separator + str(rand.randint(weight_scale[0],
weight_scale[1])) + "\n")