Added handing of directed graphs to a_star and dijkstra as well as to reading graphs from file.
This commit is contained in:
parent
8c680e235e
commit
55f1ecc36c
@ -2,7 +2,7 @@ def heuristic_cost(start, goal, graph):
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def a_star_algorithm(graph, point_set, start, goal, h=heuristic_cost):
|
def a_star_algorithm(graph, start, goal, h=heuristic_cost, is_directed=False):
|
||||||
def return_path_and_weight(c_f, c, s):
|
def return_path_and_weight(c_f, c, s):
|
||||||
current_node = c_f[c]
|
current_node = c_f[c]
|
||||||
shortest_path = [c, current_node]
|
shortest_path = [c, current_node]
|
||||||
@ -12,15 +12,24 @@ def a_star_algorithm(graph, point_set, start, goal, h=heuristic_cost):
|
|||||||
weight = 0
|
weight = 0
|
||||||
shortest_path.reverse()
|
shortest_path.reverse()
|
||||||
for k in range(len(shortest_path) - 1):
|
for k in range(len(shortest_path) - 1):
|
||||||
if shortest_path[k] > shortest_path[k+1]:
|
if not is_directed:
|
||||||
weight += graph[(shortest_path[k], shortest_path[k+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])]
|
||||||
else:
|
else:
|
||||||
weight += graph[(shortest_path[k + 1], shortest_path[k])]
|
weight += graph[(shortest_path[k], shortest_path[k + 1])]
|
||||||
return shortest_path, weight
|
return shortest_path, weight
|
||||||
|
|
||||||
for edge in graph.keys():
|
point_set = dict()
|
||||||
point_set[edge[0]].append(edge[1])
|
for arc in g.keys():
|
||||||
point_set[edge[1]].append(edge[0])
|
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])
|
||||||
|
|
||||||
open_set = set()
|
open_set = set()
|
||||||
open_set.add(start)
|
open_set.add(start)
|
||||||
@ -43,10 +52,13 @@ def a_star_algorithm(graph, point_set, start, goal, h=heuristic_cost):
|
|||||||
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]
|
||||||
if current > neighbor:
|
if not is_directed:
|
||||||
tentative_g_score += graph[(current, neighbor)]
|
if current > neighbor:
|
||||||
|
tentative_g_score += graph[(current, neighbor)]
|
||||||
|
else:
|
||||||
|
tentative_g_score += graph[(neighbor, current)]
|
||||||
else:
|
else:
|
||||||
tentative_g_score += graph[(neighbor, current)]
|
tentative_g_score += graph[(current, neighbor)]
|
||||||
if tentative_g_score < g_score[neighbor]:
|
if tentative_g_score < g_score[neighbor]:
|
||||||
came_from[neighbor] = current
|
came_from[neighbor] = current
|
||||||
g_score[neighbor] = tentative_g_score
|
g_score[neighbor] = tentative_g_score
|
||||||
@ -72,9 +84,15 @@ if __name__ == "__main__":
|
|||||||
(9, 1): 8
|
(9, 1): 8
|
||||||
}
|
}
|
||||||
|
|
||||||
v = dict()
|
g2 = {
|
||||||
for i in g.keys():
|
(4, 1): 6,
|
||||||
v[i[0]] = []
|
(1, 3): 4,
|
||||||
v[i[1]] = []
|
(1, 2): 2,
|
||||||
|
(2, 4): 5,
|
||||||
|
(3, 4): 1,
|
||||||
|
(5, 3): 1
|
||||||
|
}
|
||||||
|
|
||||||
print(a_star_algorithm(g, v, 7, 10, heuristic_cost))
|
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))
|
||||||
|
@ -3,7 +3,7 @@ import heapq as heap
|
|||||||
|
|
||||||
# function which takes graph, vertex set, start and goal, uses djikstra algorithm to establish shortest paths from start
|
# 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
|
# every other vertex in graph and returns shortest path between start and goal
|
||||||
def dijkstra_algorithm(graph, point_set, start, goal):
|
def dijkstra_algorithm(graph, start, goal, is_directed=False):
|
||||||
# dictionary which will store for every vertex it's distance to start
|
# dictionary which will store for every vertex it's distance to start
|
||||||
dist = dict()
|
dist = dict()
|
||||||
|
|
||||||
@ -16,10 +16,16 @@ def dijkstra_algorithm(graph, point_set, start, goal):
|
|||||||
# list which is used to keep priority queue with vertexes to be explored by the algorithm
|
# list which is used to keep priority queue with vertexes to be explored by the algorithm
|
||||||
queue = []
|
queue = []
|
||||||
|
|
||||||
|
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
|
# creating dictionary which for every vertex keeps all it's neighbors
|
||||||
for edge in graph.keys():
|
for arc in graph.keys():
|
||||||
point_set[edge[0]].append(edge[1])
|
point_set[arc[0]].append(arc[1])
|
||||||
point_set[edge[1]].append(edge[0])
|
if not is_directed:
|
||||||
|
point_set[arc[1]].append(arc[0])
|
||||||
|
|
||||||
for vertex in point_set:
|
for vertex in point_set:
|
||||||
dist[vertex] = float('inf')
|
dist[vertex] = float('inf')
|
||||||
@ -34,11 +40,13 @@ def dijkstra_algorithm(graph, point_set, start, goal):
|
|||||||
current = heap.heappop(queue)
|
current = heap.heappop(queue)
|
||||||
for neighbor in point_set[current[1]]:
|
for neighbor in point_set[current[1]]:
|
||||||
new_dist = 0
|
new_dist = 0
|
||||||
if neighbor > current[1]:
|
if not is_directed:
|
||||||
new_dist = dist[current[1]] + graph[(neighbor, current[1])]
|
if neighbor > current[1]:
|
||||||
|
new_dist = dist[current[1]] + graph[(neighbor, current[1])]
|
||||||
|
else:
|
||||||
|
new_dist = dist[current[1]] + graph[(current[1], neighbor)]
|
||||||
else:
|
else:
|
||||||
new_dist = dist[current[1]] + graph[(current[1], neighbor)]
|
new_dist = dist[current[1]] + graph[(current[1], neighbor)]
|
||||||
|
|
||||||
if new_dist < dist[neighbor]:
|
if new_dist < dist[neighbor]:
|
||||||
dist[neighbor] = new_dist
|
dist[neighbor] = new_dist
|
||||||
for k in range(len(queue)):
|
for k in range(len(queue)):
|
||||||
@ -76,9 +84,15 @@ if __name__ == "__main__":
|
|||||||
(9, 1): 8
|
(9, 1): 8
|
||||||
}
|
}
|
||||||
|
|
||||||
v = dict()
|
g2 = {
|
||||||
for i in g.keys():
|
(4, 1): 6,
|
||||||
v[i[0]] = []
|
(1, 3): 4,
|
||||||
v[i[1]] = []
|
(1, 2): 2,
|
||||||
|
(2, 4): 5,
|
||||||
|
(3, 4): 1,
|
||||||
|
(5, 3): 1
|
||||||
|
}
|
||||||
|
|
||||||
print(dijkstra_algorithm(g, v, 7, 10))
|
print('')
|
||||||
|
print(dijkstra_algorithm(g, 7, 10))
|
||||||
|
print(dijkstra_algorithm(g2, 1, 5, is_directed=True))
|
||||||
|
@ -15,10 +15,10 @@ def read_graph_from_file(path, separator=",", read_first_line=False, is_directed
|
|||||||
if not is_directed:
|
if not is_directed:
|
||||||
if node1 < node2:
|
if node1 < node2:
|
||||||
node1, node2 = node2, node1
|
node1, node2 = node2, node1
|
||||||
if not has_weight:
|
if not has_weight:
|
||||||
edges[(node1, node2)] = 1
|
edges[(node1, node2)] = 1
|
||||||
else:
|
else:
|
||||||
edges[(node1, node2)] = int(split[2])
|
edges[(node1, node2)] = int(split[2])
|
||||||
else:
|
else:
|
||||||
read_line = True
|
read_line = True
|
||||||
line = file.readline()
|
line = file.readline()
|
||||||
|
Loading…
Reference in New Issue
Block a user