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:
parent
e9cda32103
commit
a530372141
@ -1,9 +1,2 @@
|
||||
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
|
@ -1,101 +1,71 @@
|
||||
import fibheap
|
||||
import math
|
||||
|
||||
|
||||
def heuristic_cost(start, goal, graph):
|
||||
def heuristic_cost(node1, node2):
|
||||
return 0
|
||||
|
||||
|
||||
def a_star_algorithm(graph, start, goal, h=heuristic_cost, is_directed=False):
|
||||
def return_path_and_weight(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])]
|
||||
def heuristic_cost_manhattan(node1, node2):
|
||||
part1 = (node1[0]-node2[0])**2
|
||||
part1 = part1
|
||||
part2 = (node1[1]-node2[1])**2
|
||||
return math.sqrt(part1 + part2)
|
||||
|
||||
|
||||
def a_star_algorithm(s, t, N, A, w, h):
|
||||
if s == t:
|
||||
return [s], 0
|
||||
|
||||
H = fibheap.makefheap()
|
||||
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:
|
||||
weight += graph[(shortest_path[k + 1], shortest_path[k])]
|
||||
else:
|
||||
weight += graph[(shortest_path[k], shortest_path[k + 1])]
|
||||
return shortest_path, weight
|
||||
|
||||
point_set = dict()
|
||||
for arc in g.keys():
|
||||
point_set[arc[0]] = []
|
||||
point_set[arc[1]] = []
|
||||
|
||||
for arc in graph.keys():
|
||||
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]
|
||||
d[j] = path_sum
|
||||
H.decrease_key(heap_node_connection[j], f[j])
|
||||
if success:
|
||||
path = [t]
|
||||
current_node = t
|
||||
while pred[current_node] is not None:
|
||||
path.append(pred[current_node])
|
||||
current_node = pred[current_node]
|
||||
path.reverse()
|
||||
return path, d[t]
|
||||
return None, None
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
g = {
|
||||
(2, 1): 3,
|
||||
(3, 2): 2,
|
||||
(5, 3): 1,
|
||||
(9, 5): 5,
|
||||
(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
|
||||
}
|
||||
N = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||
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]}
|
||||
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]}
|
||||
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}
|
||||
print(a_star_algorithm(1, 10, N, A, w, heuristic_cost))
|
||||
|
||||
g2 = {
|
||||
(4, 1): 6,
|
||||
(1, 3): 4,
|
||||
(1, 2): 2,
|
||||
(2, 4): 5,
|
||||
(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))
|
||||
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)}
|
||||
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)]}
|
||||
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)]}
|
||||
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}
|
||||
print(a_star_algorithm((3, 3), (4, 8), N, A, w, heuristic_cost_manhattan))
|
||||
|
@ -1,191 +1,135 @@
|
||||
def heuristic_cost(start, goal, graph):
|
||||
import fibheap
|
||||
import math
|
||||
|
||||
|
||||
def heuristic_cost(node1, node2):
|
||||
return 0
|
||||
|
||||
|
||||
def bidirectional_algorithm(graph, start, goal, h=heuristic_cost, is_directed=False):
|
||||
def return_path_and_weight_front(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
|
||||
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])]
|
||||
def heuristic_cost_manhattan(node1, node2):
|
||||
part1 = (node1[0]-node2[0])**2
|
||||
part1 = part1
|
||||
part2 = (node1[1]-node2[1])**2
|
||||
return math.sqrt(part1 + part2)
|
||||
|
||||
|
||||
def bidirectional_algorithm(s, t, N, A, A_b, w, h):
|
||||
if s == t:
|
||||
return [s], 0
|
||||
|
||||
H_f = fibheap.makefheap()
|
||||
H_b = fibheap.makefheap()
|
||||
|
||||
d_f = {}
|
||||
d_b = {}
|
||||
heap_node_connection_f = {}
|
||||
heap_node_connection_b = {}
|
||||
pred_f = {}
|
||||
pred_b = {}
|
||||
f_f = {}
|
||||
f_b = {}
|
||||
perm_f = {}
|
||||
perm_b = {}
|
||||
|
||||
for i in N:
|
||||
d_f[i] = float('inf')
|
||||
d_b[i] = float('inf')
|
||||
perm_f[i] = False
|
||||
perm_b[i] = False
|
||||
|
||||
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:
|
||||
weight += graph[(shortest_path[k + 1], shortest_path[k])]
|
||||
d_f[j] = path_sum
|
||||
H_f.decrease_key(heap_node_connection_f[j], f_f[j])
|
||||
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])]
|
||||
perm_f[i_f] = True
|
||||
heap_node_connection_f[i_f] = fibheap.fheappush(H_f, f_f[i_f], i_f)
|
||||
if perm_f[i_b] or i_b == s:
|
||||
ending_node = i_b
|
||||
success = True
|
||||
break
|
||||
for j in A_b[i_b]:
|
||||
path_sum = d_b[i_b] + w[(j, i_b)]
|
||||
if d_b[j] > path_sum:
|
||||
pred_b[j] = i_b
|
||||
f_b[j] = path_sum + h(j, s)
|
||||
if d_b[j] == float('inf'):
|
||||
d_b[j] = path_sum
|
||||
heap_node_connection_b[j] = fibheap.fheappush(H_b, f_b[j], j)
|
||||
else:
|
||||
weight += graph[(shortest_path[k + 1], shortest_path[k])]
|
||||
d_b[j] = path_sum
|
||||
H_b.decrease_key(heap_node_connection_b[j], f_b[j])
|
||||
if success:
|
||||
if ending_node == t:
|
||||
path = [t]
|
||||
current_node = ending_node
|
||||
while pred_f[current_node] is not None:
|
||||
path.append(pred_f[current_node])
|
||||
current_node = pred_f[current_node]
|
||||
path.reverse()
|
||||
return path, d_f[t]
|
||||
elif ending_node == s:
|
||||
path = [s]
|
||||
current_node = s
|
||||
while pred_b[current_node] is not None:
|
||||
path.append(pred_b[current_node])
|
||||
current_node = pred_b[current_node]
|
||||
return path, d_b[s]
|
||||
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):
|
||||
shortest_path_front, weight_front = return_path_and_weight_front(c_f_f, c_f, s)
|
||||
shortest_path_back, weight_back = return_path_and_weight_back(c_f_b, c_f, g)
|
||||
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):
|
||||
shortest_path_front, weight_front = return_path_and_weight_front(c_f_f, c_b, s)
|
||||
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()
|
||||
point_set_back = dict()
|
||||
for arc in g.keys():
|
||||
point_set_front[arc[0]] = []
|
||||
point_set_front[arc[1]] = []
|
||||
point_set_back[arc[0]] = []
|
||||
point_set_back[arc[1]] = []
|
||||
|
||||
for arc in graph.keys():
|
||||
point_set_front[arc[0]].append(arc[1])
|
||||
if not is_directed:
|
||||
point_set_back[arc[1]].append(arc[0])
|
||||
point_set_front[arc[1]].append(arc[0])
|
||||
point_set_back[arc[0]].append(arc[1])
|
||||
else:
|
||||
point_set_back[arc[1]].append(arc[0])
|
||||
|
||||
open_set_front = set()
|
||||
open_set_front.add(start)
|
||||
|
||||
open_set_back = set()
|
||||
open_set_back.add(goal)
|
||||
|
||||
came_from_front = {}
|
||||
came_from_back = {}
|
||||
|
||||
g_score_front = {k: float('inf') for k in point_set_front.keys()}
|
||||
g_score_front[start] = 0
|
||||
|
||||
g_score_back = {k: float('inf') for k in point_set_back.keys()}
|
||||
g_score_back[goal] = 0
|
||||
|
||||
f_score_front = {k: float('inf') for k in point_set_front.keys()}
|
||||
f_score_front[start] = h(start, goal, graph)
|
||||
|
||||
f_score_back = {k: float('inf') for k in point_set_back.keys()}
|
||||
f_score_back[goal] = h(goal, start, graph)
|
||||
|
||||
while len(open_set_front) > 0 and len(open_set_back) > 0:
|
||||
current_front = list(open_set_front)[0]
|
||||
current_back = list(open_set_back)[0]
|
||||
|
||||
for k in open_set_front:
|
||||
if f_score_front[k] < f_score_front[current_front]:
|
||||
current_front = k
|
||||
|
||||
for k in open_set_back:
|
||||
if f_score_back[k] < f_score_back[current_back]:
|
||||
current_back = k
|
||||
|
||||
if current_front == goal:
|
||||
return return_path_and_weight_front(came_from_front, current_front, start)
|
||||
|
||||
if current_back == start:
|
||||
return return_path_and_weight_back(came_from_back, current_back, goal)
|
||||
|
||||
if current_front in came_from_back.keys() and current_back in came_from_front.keys():
|
||||
path1, weight1 = return_path_and_weight_front_meet_back(came_from_front, came_from_back, current_front,
|
||||
start, goal)
|
||||
path2, weight2 = return_path_and_weight_back_meet_front(came_from_front, came_from_back, current_back,
|
||||
start, goal)
|
||||
if weight1 < weight2:
|
||||
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)
|
||||
path1 = [ending_node]
|
||||
current_node = ending_node
|
||||
while pred_f[current_node] is not None:
|
||||
path1.append(pred_f[current_node])
|
||||
current_node = pred_f[current_node]
|
||||
path1.reverse()
|
||||
path2 = []
|
||||
current_node = ending_node
|
||||
while pred_b[current_node] is not None:
|
||||
path2.append(pred_b[current_node])
|
||||
current_node = pred_b[current_node]
|
||||
return path1 + path2, d_f[ending_node] + d_b[ending_node]
|
||||
return None, None
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
g = {
|
||||
(2, 1): 3,
|
||||
(3, 2): 2,
|
||||
(5, 3): 1,
|
||||
(9, 5): 5,
|
||||
(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
|
||||
}
|
||||
N = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||
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]}
|
||||
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]}
|
||||
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}
|
||||
print(bidirectional_algorithm(1, 10, N, A, A_b, w, heuristic_cost))
|
||||
|
||||
g2 = {
|
||||
(4, 1): 6,
|
||||
(1, 3): 4,
|
||||
(1, 2): 2,
|
||||
(2, 4): 5,
|
||||
(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))
|
||||
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)}
|
||||
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)]}
|
||||
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)]}
|
||||
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}
|
||||
print(bidirectional_algorithm((3, 3), (4, 8), N, A, A_b, w, heuristic_cost_manhattan))
|
||||
|
@ -1,119 +1,64 @@
|
||||
import heapq as heap
|
||||
import fibheap
|
||||
|
||||
|
||||
# function which takes graph, vertex set, start and goal, uses djikstra algorithm to establish shortest paths from start
|
||||
# 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()
|
||||
def dijkstra_algorithm(s, t, N, A, w):
|
||||
"""
|
||||
|
||||
# dictionary which keeps if vertex was already popped from queue
|
||||
visited = dict()
|
||||
:param graph:
|
||||
: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
|
||||
prev = dict()
|
||||
H = fibheap.makefheap()
|
||||
d = {}
|
||||
heap_node_connection = {}
|
||||
pred = {}
|
||||
|
||||
# list which is used to keep priority queue with vertexes to be explored by the algorithm
|
||||
queue = []
|
||||
|
||||
# dictionary for keeping neighbors of vertexes.
|
||||
point_set = dict()
|
||||
for arc in graph.keys():
|
||||
point_set[arc[0]] = []
|
||||
point_set[arc[1]] = []
|
||||
|
||||
# creating dictionary which for every vertex keeps all it's neighbors
|
||||
for arc in graph.keys():
|
||||
point_set[arc[0]].append(arc[1])
|
||||
if not is_directed:
|
||||
point_set[arc[1]].append(arc[0])
|
||||
|
||||
# initialization of needed lists
|
||||
for vertex in point_set:
|
||||
# setting distance of every vertex from the starting vertex to infinity
|
||||
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])]
|
||||
for i in N:
|
||||
d[i] = float('inf')
|
||||
d[s] = 0
|
||||
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
|
||||
if d[j] == float('inf'):
|
||||
d[j] = path_sum
|
||||
heap_node_connection[j] = fibheap.fheappush(H, path_sum, j)
|
||||
else:
|
||||
new_dist = dist[current[1]] + graph[(current[1], neighbor)]
|
||||
else:
|
||||
new_dist = dist[current[1]] + graph[(current[1], neighbor)]
|
||||
if new_dist < dist[neighbor]:
|
||||
if dist[neighbor] == float('inf'):
|
||||
dist[neighbor] = new_dist
|
||||
prev[neighbor] = current[1]
|
||||
heap_node_connection[neighbor] = fibheap.fheappush(node_heap, new_dist, neighbor)
|
||||
# heap.heappush(queue, (new_dist, neighbor))
|
||||
else:
|
||||
dist[neighbor] = new_dist
|
||||
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]
|
||||
d[j] = path_sum
|
||||
H.decrease_key(heap_node_connection[j], path_sum)
|
||||
if success:
|
||||
path = [t]
|
||||
current_node = t
|
||||
while pred[current_node] is not None:
|
||||
path.append(pred[current_node])
|
||||
current_node = pred[current_node]
|
||||
path.reverse()
|
||||
return path, d[t]
|
||||
return None, None
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
g1 = {
|
||||
(2, 1): 3,
|
||||
(3, 2): 2,
|
||||
(5, 3): 1,
|
||||
(9, 5): 5,
|
||||
(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
|
||||
}
|
||||
N = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||
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]}
|
||||
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]}
|
||||
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}
|
||||
print(dijkstra_algorithm(1, 10, N, A, w))
|
||||
|
||||
g2 = {
|
||||
(4, 1): 6,
|
||||
(1, 3): 4,
|
||||
(1, 2): 2,
|
||||
(2, 4): 5,
|
||||
(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))
|
||||
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)}
|
||||
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)]}
|
||||
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)]}
|
||||
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}
|
||||
print(dijkstra_algorithm((3, 3), (4, 8), N, A, w))
|
||||
|
118
dataset/generate_graph.py
Normal file
118
dataset/generate_graph.py
Normal 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
162
dataset/generate_grid.py
Normal 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
13536
dataset/graphs/graph1
Normal file
File diff suppressed because it is too large
Load Diff
10282
dataset/graphs/graph10
Normal file
10282
dataset/graphs/graph10
Normal file
File diff suppressed because it is too large
Load Diff
8320
dataset/graphs/graph2
Normal file
8320
dataset/graphs/graph2
Normal file
File diff suppressed because it is too large
Load Diff
12404
dataset/graphs/graph3
Normal file
12404
dataset/graphs/graph3
Normal file
File diff suppressed because it is too large
Load Diff
14570
dataset/graphs/graph4
Normal file
14570
dataset/graphs/graph4
Normal file
File diff suppressed because it is too large
Load Diff
8824
dataset/graphs/graph5
Normal file
8824
dataset/graphs/graph5
Normal file
File diff suppressed because it is too large
Load Diff
10980
dataset/graphs/graph6
Normal file
10980
dataset/graphs/graph6
Normal file
File diff suppressed because it is too large
Load Diff
8566
dataset/graphs/graph7
Normal file
8566
dataset/graphs/graph7
Normal file
File diff suppressed because it is too large
Load Diff
12582
dataset/graphs/graph8
Normal file
12582
dataset/graphs/graph8
Normal file
File diff suppressed because it is too large
Load Diff
15104
dataset/graphs/graph9
Normal file
15104
dataset/graphs/graph9
Normal file
File diff suppressed because it is too large
Load Diff
147908
dataset/grids/grid1
Normal file
147908
dataset/grids/grid1
Normal file
File diff suppressed because it is too large
Load Diff
184054
dataset/grids/grid10
Normal file
184054
dataset/grids/grid10
Normal file
File diff suppressed because it is too large
Load Diff
76278
dataset/grids/grid2
Normal file
76278
dataset/grids/grid2
Normal file
File diff suppressed because it is too large
Load Diff
128018
dataset/grids/grid3
Normal file
128018
dataset/grids/grid3
Normal file
File diff suppressed because it is too large
Load Diff
141502
dataset/grids/grid4
Normal file
141502
dataset/grids/grid4
Normal file
File diff suppressed because it is too large
Load Diff
234902
dataset/grids/grid5
Normal file
234902
dataset/grids/grid5
Normal file
File diff suppressed because it is too large
Load Diff
103124
dataset/grids/grid6
Normal file
103124
dataset/grids/grid6
Normal file
File diff suppressed because it is too large
Load Diff
167940
dataset/grids/grid7
Normal file
167940
dataset/grids/grid7
Normal file
File diff suppressed because it is too large
Load Diff
76494
dataset/grids/grid8
Normal file
76494
dataset/grids/grid8
Normal file
File diff suppressed because it is too large
Load Diff
74702
dataset/grids/grid9
Normal file
74702
dataset/grids/grid9
Normal file
File diff suppressed because it is too large
Load Diff
198
main.py
198
main.py
@ -1,15 +1,195 @@
|
||||
import tools.file_service as op_file
|
||||
import algorithms.dijkstra as dijkstra
|
||||
import algorithms.a_star as a_star
|
||||
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__':
|
||||
g = op_file.read_graph_from_file("dataset/deezer_clean_data/HR_edges_with_weight.csv", has_weight=True)
|
||||
v = dict()
|
||||
for i in g.keys():
|
||||
v[i[0]] = []
|
||||
v[i[1]] = []
|
||||
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/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))
|
||||
# print(a_star.a_star_algorithm(g, v, 0, 4))
|
||||
# print(bidirectional.bidirectional_algorithm(g, v, 0, 4))
|
||||
startTime = time.time()
|
||||
tracemalloc.start()
|
||||
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")
|
||||
|
@ -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")
|
Loading…
Reference in New Issue
Block a user