Changed dijkstra_algorithm a little. Added printout of the shortest path and weight in the a_star_algorithm. Added implementation of bidirectional algorithm. Still need good heuristic function for A* and bidirectional algorithms.
This commit is contained in:
parent
602b893f81
commit
85995b3d16
@ -3,23 +3,43 @@ def heuristic_cost(start, goal, graph):
|
|||||||
|
|
||||||
|
|
||||||
def a_star_algorithm(graph, point_set, start, goal, h=heuristic_cost):
|
def a_star_algorithm(graph, point_set, start, goal, h=heuristic_cost):
|
||||||
|
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 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])]
|
||||||
|
return shortest_path, weight
|
||||||
|
|
||||||
for edge in graph.keys():
|
for edge in graph.keys():
|
||||||
point_set[edge[0]].append(edge[1])
|
point_set[edge[0]].append(edge[1])
|
||||||
point_set[edge[1]].append(edge[0])
|
point_set[edge[1]].append(edge[0])
|
||||||
|
|
||||||
open_set = set()
|
open_set = set()
|
||||||
open_set.add(start)
|
open_set.add(start)
|
||||||
|
|
||||||
came_from = {}
|
came_from = {}
|
||||||
|
|
||||||
g_score = {k: float('inf') for k in point_set.keys()}
|
g_score = {k: float('inf') for k in point_set.keys()}
|
||||||
g_score[start] = 0
|
g_score[start] = 0
|
||||||
|
|
||||||
f_score = {k: float('inf') for k in point_set.keys()}
|
f_score = {k: float('inf') for k in point_set.keys()}
|
||||||
f_score[start] = h(start, goal, graph)
|
f_score[start] = h(start, goal, graph)
|
||||||
|
|
||||||
while len(open_set) > 0:
|
while len(open_set) > 0:
|
||||||
current = list(open_set)[0]
|
current = list(open_set)[0]
|
||||||
for k in open_set:
|
for k in open_set:
|
||||||
if f_score[k] < f_score[current]:
|
if f_score[k] < f_score[current]:
|
||||||
current = k
|
current = k
|
||||||
if current == goal:
|
if current == goal:
|
||||||
return came_from, current
|
return return_path_and_weight(came_from, current, start)
|
||||||
open_set.remove(current)
|
open_set.remove(current)
|
||||||
for neighbor in point_set[current]:
|
for neighbor in point_set[current]:
|
||||||
tentative_g_score = g_score[current]
|
tentative_g_score = g_score[current]
|
||||||
|
@ -0,0 +1,150 @@
|
|||||||
|
def heuristic_cost(start, goal, graph):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def bidirectional_algorithm(graph, point_set, start, goal, h=heuristic_cost):
|
||||||
|
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 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])]
|
||||||
|
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 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])]
|
||||||
|
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_back(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()
|
||||||
|
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_back(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()
|
||||||
|
return shortest_path_front + shortest_path_back[1:], weight_front + weight_back
|
||||||
|
|
||||||
|
for edge in graph.keys():
|
||||||
|
point_set[edge[0]].append(edge[1])
|
||||||
|
point_set[edge[1]].append(edge[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.keys()}
|
||||||
|
g_score_front[start] = 0
|
||||||
|
|
||||||
|
g_score_back = {k: float('inf') for k in point_set.keys()}
|
||||||
|
g_score_back[goal] = 0
|
||||||
|
|
||||||
|
f_score_front = {k: float('inf') for k in point_set.keys()}
|
||||||
|
f_score_front[start] = h(start, goal, graph)
|
||||||
|
|
||||||
|
f_score_back = {k: float('inf') for k in point_set.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():
|
||||||
|
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[current_front]:
|
||||||
|
tentative_g_score = g_score_front[current_front]
|
||||||
|
|
||||||
|
if current_front > neighbor:
|
||||||
|
tentative_g_score += graph[(current_front, neighbor)]
|
||||||
|
else:
|
||||||
|
tentative_g_score += graph[(neighbor, current_front)]
|
||||||
|
|
||||||
|
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[current_back]:
|
||||||
|
tentative_g_score = g_score_back[current_back]
|
||||||
|
|
||||||
|
if current_back > neighbor:
|
||||||
|
tentative_g_score += graph[(current_back, neighbor)]
|
||||||
|
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__":
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
v = dict()
|
||||||
|
for i in g.keys():
|
||||||
|
v[i[0]] = []
|
||||||
|
v[i[1]] = []
|
||||||
|
|
||||||
|
print(bidirectional_algorithm(g, v, 7, 8, heuristic_cost))
|
@ -26,8 +26,8 @@ def dijkstra_algorithm(graph, point_set, start, goal):
|
|||||||
prev[vertex] = None
|
prev[vertex] = None
|
||||||
visited[vertex] = False
|
visited[vertex] = False
|
||||||
|
|
||||||
dist[start] = 0
|
|
||||||
heap.heappush(queue, (0, start))
|
heap.heappush(queue, (0, start))
|
||||||
|
dist[start] = 0
|
||||||
visited[start] = True
|
visited[start] = True
|
||||||
|
|
||||||
while len(queue) > 0:
|
while len(queue) > 0:
|
||||||
@ -41,6 +41,10 @@ def dijkstra_algorithm(graph, point_set, start, goal):
|
|||||||
|
|
||||||
if new_dist < dist[neighbor]:
|
if new_dist < dist[neighbor]:
|
||||||
dist[neighbor] = new_dist
|
dist[neighbor] = new_dist
|
||||||
|
for k in range(len(queue)):
|
||||||
|
if queue[k][1] == neighbor:
|
||||||
|
queue[k] = (new_dist, neighbor)
|
||||||
|
heap.heapify(queue)
|
||||||
prev[neighbor] = current[1]
|
prev[neighbor] = current[1]
|
||||||
|
|
||||||
if not visited[neighbor]:
|
if not visited[neighbor]:
|
||||||
@ -51,6 +55,7 @@ def dijkstra_algorithm(graph, point_set, start, goal):
|
|||||||
while prev[temp] is not None:
|
while prev[temp] is not None:
|
||||||
shortest_path.append(prev[temp])
|
shortest_path.append(prev[temp])
|
||||||
temp = prev[temp]
|
temp = prev[temp]
|
||||||
|
shortest_path.reverse()
|
||||||
return shortest_path, dist[goal]
|
return shortest_path, dist[goal]
|
||||||
|
|
||||||
|
|
||||||
@ -67,7 +72,8 @@ if __name__ == "__main__":
|
|||||||
(3, 1): 4,
|
(3, 1): 4,
|
||||||
(6, 2): 3,
|
(6, 2): 3,
|
||||||
(8, 6): 8,
|
(8, 6): 8,
|
||||||
(8, 3): 2
|
(8, 3): 2,
|
||||||
|
(9, 1): 8
|
||||||
}
|
}
|
||||||
|
|
||||||
v = dict()
|
v = dict()
|
||||||
|
6
main.py
6
main.py
@ -1,5 +1,7 @@
|
|||||||
import tools.file_service as op_file
|
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.bidirectional as bidirectional
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
g = op_file.read_graph_from_file("dataset/deezer_clean_data/HR_edgeswith_weight.csv", has_weight=True)
|
g = op_file.read_graph_from_file("dataset/deezer_clean_data/HR_edgeswith_weight.csv", has_weight=True)
|
||||||
@ -8,4 +10,6 @@ if __name__ == '__main__':
|
|||||||
v[i[0]] = []
|
v[i[0]] = []
|
||||||
v[i[1]] = []
|
v[i[1]] = []
|
||||||
|
|
||||||
print(dijkstra.dijkstra_algorithm(g, v, 0, 4))
|
# 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))
|
||||||
|
Loading…
Reference in New Issue
Block a user