Алгоритмы поиска маршрута на графике

Постановка задачи

Я пытаюсь реализовать DFS, BFS и UCS (поиск единой стоимости), чтобы найти маршруты между разными железнодорожными станциями с помощью этого файла CSV . Если вы откроете файл данных с помощью любого текстового редактора, вы увидите содержимое файла как:

      "Harrow & Wealdstone", "Kenton", "Bakerloo", 3, "5", "0"
"Kenton", "South Kenton", "Bakerloo", 2, "4", "0"
· · ·
"Bank/Monument", "Waterloo", "Waterloo & City", 4, "1", "0"

Каждая строка в CSV-файле представляет собой «шаг» Tube и имеет следующий формат:

      [StartingStation], [EndingStation], [TubeLine], [AverageTimeTaken], [MainZone], [SecondaryZone]

куда:

  • StartingStation: начальная станция
  • EndingStation: конечная станция с прямым подключением
  • TubeLine: линия метро, ​​соединяющая названные станции
  • AverageTimeTaken: среднее время в минутах между указанными станциями.
  • MainZone: основная зона станций
  • SecondaryZone: дополнительная зона станций, которая равна «0», если станция находится только в одной зоне.

Я реализовал алгоритмы поиска, но у меня возникли проблемы с преобразованием данных CSV в подходящий граф (с использованием NetworkX) в качестве входных данных для алгоритмов.

Я хочу напечатать информацию, относящуюся к поиску, например станции, стоимость, количество развернутых узлов и т. Д. В настоящее время, когда я вызываю блок кода визуализации графика, я получаю пустой результат? Как представить состояние и как построить новое состояние из каждой станции, доступной из станции в текущем состоянии, но еще не посещенной на текущем пути? Спасибо.

Реализации

Визуализация графика

      import pandas as pd
import networkx as nx
import matplotlib.pyplot  as plt

tube_data = pd.read_csv('tubedata.csv')
Graphtype = nx.Graph()
tube_data = nx.read_edgelist(tube_data, delimiter=',')
      def show_weighted_graph(networkx_graph, node_size, font_size, fig_size):
  plt.figure(num=None, figsize=fig_size, dpi=80)
  plt.axis('off')
  nodes_position = nx.spring_layout(networkx_graph) 
  edges_weights  = nx.get_edge_attributes(networkx_graph,'weight')

  nx.draw_networkx_nodes(networkx_graph, nodes_position, node_size=node_size,  
                         node_color = ["orange"]*networkx_graph.number_of_nodes())

  nx.draw_networkx_edges(networkx_graph, nodes_position, 
                         edgelist=list(networkx_graph.edges), width=2)

  nx.draw_networkx_edge_labels(networkx_graph, nodes_position, 
                               edge_labels = edges_weights)

  nx.draw_networkx_labels(networkx_graph, nodes_position, font_size=font_size, 
                          font_family='sans-serif')
  plt.axis('off')
  plt.show()

DFS

      def dfs(graph, origin, destination, already_visited = [], count=1, reverse=False):
  if origin == destination:
    return [origin],count+1
  
  next_already_visited = already_visited.copy()
  next_already_visited.append(origin)
  
  neighbours = reversed(list(graph.neighbors(origin))) if reverse else graph.neighbors(origin)
  for next_node in neighbours: 
    if next_node not in already_visited:
      result, count= dfs(graph, next_node, destination, next_already_visited, count, reverse)
      if result != []:
        path = [origin] + result
        return path,count+1

  return [],count+1

BFS

      def bfs(graph, origin, destination, counter = 0, reverse=False):
  next_already_visited = [origin]
  total_paths = [[origin]] 

  while len(total_paths)!= 0: 
    new_total_paths = []
    for path in total_paths:
      last_element_in_path = path[-1]
      nodes_found = list(reversed(list(graph.neighbors(last_element_in_path)))) if reverse else list(graph.neighbors(last_element_in_path))
      if destination in nodes_found:
        return path + [destination], counter+1

      for node in nodes_found:
        if node not in next_already_visited:
          counter += 1
          next_already_visited.append(node)
          new_total_paths = new_total_paths + [path + [node]]
    
    total_paths = new_total_paths

  return [],-1

UCS

      from queue import PriorityQueue

def h(node): # Calculates the admissible heuristic of a node, format is [X,Y]
    node = node.replace('[','')
    node = node.replace(']','')
    x, y = node.split(',', maxsplit=2)
    x = float(x)
    y = float(y)
    return abs(x-9) + abs(y-9)

def Astar(graph, origin, goal):
    admissible_heuristics = {} 
    h = heuristic(origin)
    admissible_heuristics[origin] = h
    visited_nodes = {}
    visited_nodes[origin] = (h, [origin]) 

    paths_to_explore = PriorityQueue()
    paths_to_explore.put((h, [origin], 0)) 
    while not paths_to_explore.empty(): 
        _, path, total_cost = paths_to_explore.get()
        current_node = path[-1]
        neighbors = graph.neighbors(current_node) 
        
        for neighbor in neighbors:
            edge_data = graph.get_edge_data(path[-1], neighbor)
            if "weight" in edge_data:
                cost_to_neighbor = edge_data["weight"] 
            else:
                cost_to_neighbor = 1 

            if neighbor in admissible_heuristics:
                h = admissible_heuristics[neighbor]
            else:
                h = heuristic(neighbor)
                admissible_heuristics[neighbor] = h

            new_cost = total_cost + cost_to_neighbor
            new_cost_plus_h = new_cost + h
            if (neighbor not in visited_nodes) or (visited_nodes[neighbor][0]>new_cost_plus_h): 
                next_node = (new_cost_plus_h, path+[neighbor], new_cost)
                visited_nodes[neighbor] = next_node 
                paths_to_explore.put(next_node) 

    return visited_nodes[goal] 

0 ответов

Другие вопросы по тегам