shouldz

IA - 2 atividade: Buscas Largura e profundidade com plotagem gráfica

Jul 27th, 2022
863
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.70 KB | None | 0 0
  1. import networkx as nx
  2. import matplotlib.pyplot as plt
  3. from queue import Queue
  4.  
  5. colormap = []
  6. escolhidos = []
  7. colormapescolhidos = []
  8. dicionario = {}
  9. G = nx.Graph()
  10. varx = vary = 0
  11.  
  12. class GraphLargura:
  13.     def __init__(self, num_of_nodes, directed=True):
  14.         self.m_num_of_nodes = num_of_nodes
  15.         self.m_nodes = range(self.m_num_of_nodes)
  16.         self.m_directed = directed
  17.         self.m_adj_list = {node: set() for node in self.m_nodes}
  18.  
  19.     def add_edge(self, node1, node2, weight=1):
  20.         self.m_adj_list[node1].add((node2, weight))
  21.         if not self.m_directed:
  22.             self.m_adj_list[node2].add((node1, weight))
  23.  
  24.     def print_adj_list(self):
  25.         for key in self.m_adj_list.keys():
  26.             print("node", key, ": ", self.m_adj_list[key])
  27.  
  28.     def bfs(self, start_node, target_node):
  29.         visited = set()
  30.         queue = Queue()
  31.         queue.put(start_node)
  32.         visited.add(start_node)
  33.         parent = dict()
  34.         parent[start_node] = None
  35.         path_found = False
  36.         while not queue.empty():
  37.             current_node = queue.get()
  38.             if current_node == target_node:
  39.                 path_found = True
  40.                 break
  41.             for (next_node, weight) in self.m_adj_list[current_node]:
  42.                 if next_node not in visited:
  43.                     queue.put(next_node)
  44.                     parent[next_node] = current_node
  45.                     visited.add(next_node)
  46.         path = []
  47.         if path_found:
  48.             path.append(target_node)
  49.             while parent[target_node] is not None:
  50.                 path.append(parent[target_node])
  51.                 target_node = parent[target_node]
  52.             path.reverse()
  53.         return path
  54.  
  55. class GraphProfundidade:
  56.     def __init__(self, num_of_nodes, directed=True):
  57.         self.m_num_of_nodes = num_of_nodes
  58.         self.m_nodes = range(self.m_num_of_nodes)
  59.         self.m_directed = directed
  60.         self.m_adj_list = {node: set() for node in self.m_nodes}
  61.  
  62.     def add_edge(self, node1, node2, weight=1):
  63.         self.m_adj_list[node1].add((node2, weight))
  64.         if not self.m_directed:
  65.             self.m_adj_list[node2].add((node1, weight))
  66.     def print_adj_list(self):
  67.         for key in self.m_adj_list.keys():
  68.             print("node", key, ": ", self.m_adj_list[key])
  69.  
  70.     def dfs(self, start, target, path=[], visited=set()):
  71.         path.append(start)
  72.         visited.add(start)
  73.         if start == target:
  74.             return path
  75.         for (neighbour, weight) in self.m_adj_list[start]:
  76.             if neighbour not in visited:
  77.                 result = self.dfs(neighbour, target, path, visited)
  78.                 if result is not None:
  79.                     return result
  80.         path.pop()
  81.         return None
  82.  
  83. #Entrada
  84. x = str(input("Digite o tipo de grafo:\n1- Largura; 2- Profundidade \n"))
  85. qntNodos = int(input("Digite a quantidade de nodos: "))
  86. for i in range(qntNodos):
  87.     G.add_node(i)
  88.  
  89. #Seleção do tipo de busca
  90. if x == "1":
  91.     graph = GraphLargura(qntNodos, directed=False)
  92. elif x == "2":
  93.     graph = GraphProfundidade(qntNodos, directed=False)
  94. else:
  95.     exit()
  96.  
  97. #Entrada com nome dos nodos, escolhido pelo usuario
  98. for nomes in range(qntNodos):
  99.     entrada = str(input("Digite o nome da variável: "))
  100.     dicionario[nomes] = entrada
  101.  
  102. #Ligações entre os nodos do grafo
  103. choice = str(input("Como quer fazer as ligações: \n1- Digitando o nome atribuido a cada nodo:(Formato: FeiraNova Recife) "
  104.                    "\n2- Via números:(Formato: 0,1) "))
  105. while True:
  106.     if choice == "1":
  107.         j = str(input("Digite as ligações dos nodos(Formato: FeiraNova Recife)*Para palavras compostas, "
  108.                       "digite a palavra toda junta sem dar espaços* \n(Digite 0 para terminar as entradas): "))
  109.         if j == "0":
  110.             break
  111.         j.lower().lstrip().rstrip()
  112.         j = j.split()
  113.         for k in range(qntNodos):
  114.             if j[0] == dicionario.get(k):
  115.                 varx = k
  116.         for k in range(qntNodos):
  117.             if j[1] == dicionario.get(k):
  118.                 vary = k
  119.         graph.add_edge(varx, vary)
  120.         G.add_edge(varx, vary)
  121.     else:
  122.         j = str(input("Digite as ligações dos nodos(Formato: 0,1) \n(Digite 0 para terminar as entradas): "))
  123.         if j == "0":
  124.             break
  125.         graph.add_edge(int(j[0]), int(j[2]))
  126.         G.add_edge(int(j[0]), int(j[2]))
  127.  
  128. #Ponto de inicio e alvo de busca
  129. print("Nó criados: ")
  130. print(dicionario)
  131. inicial = str(input("Digite o nodo inicial(Start da busca) e o nodo final(Alvo da busca): \n(Formato: FeiraNova Recife): "))
  132. path = []
  133. inicial.lower().lstrip().rstrip()
  134. inicial = inicial.split()
  135. for k in range(qntNodos):
  136.     if inicial[0] == dicionario.get(k):
  137.         varx = k
  138. for k in range(qntNodos):
  139.     print(k)
  140.     if inicial[1] == dicionario.get(k):
  141.         vary = k
  142. if x == "1":
  143.     path = graph.bfs(varx, vary)
  144. else:
  145.     path = graph.dfs(varx, vary)
  146. escolhidos.append(varx)
  147. escolhidos.append(vary)
  148.  
  149. #Alterar a cor do nodo após a busca ser realidada
  150. for node in G:
  151.     if node not in path:
  152.         colormap.append('blue')
  153.     else:
  154.         colormap.append('red')
  155.  
  156. #Alterar a cor do nodo só com os alvos da busca
  157. for node in G:
  158.     if node not in escolhidos:
  159.         colormapescolhidos.append('blue')
  160.     else:
  161.         colormapescolhidos.append('yellow')
  162.  
  163. #Renomear cada nodo com nome inserido pelo usuario
  164. G = nx.relabel_nodes(G, dicionario)
  165.  
  166. #Saidas para PNG
  167. pos = nx.spring_layout(G,seed=123456789,k=0.3)
  168. nx.draw_networkx(G, with_labels=True, node_size=1200, node_color='blue', pos=pos)
  169. plt.savefig("GrafoCompleto.png")
  170. plt.close()
  171. nx.draw_networkx(G, node_color=colormap, with_labels=True, node_size=1200, pos=pos)
  172. plt.savefig("GrafoComCaminhoDefinido.png")
  173. plt.close()
  174. nx.draw_networkx(G, node_color=colormapescolhidos, with_labels=True, node_size=1200, pos=pos)
  175. plt.savefig("GrafoEscolhido.png")
  176.  
  177. #Saida Para HTML
  178. rota = []
  179. g1 = "GrafoCompleto.png"
  180. g2 = "GrafoComCaminhoDefinido.png"
  181. g3 = "GrafoEscolhido.png"
  182. gif = "https://upload.wikimedia.org/wikipedia/commons/5/5d/Breadth-First-Search-Algorithm.gif"
  183. fonte = 5
  184. for k in range(len(path)):
  185.     rota.append(str(dicionario.get(path[k])) + " > ")
  186. if x == "1":
  187.     escolha = "Busca em Largura"
  188. else:
  189.     escolha = "Busca em profundidade"
  190. style = "float:right;width:200px"
  191. saidaHtml = open("GrafoSaidaHTML.html", "w+", encoding="utf-8")
  192. saidaHtml.writelines(f"<html>"
  193.                      f"     <head>"
  194.                      f"         <tittle>"
  195.                      f"             Segunda Entrega IA"
  196.                      f"         </tittle>"
  197.                      f"     </head>"
  198.                      f"     <body>"
  199.                      f"          <img src={gif} style={style}>"
  200.                      f"          <font size={fonte}><br>Saída do grafo de entrada: <br>Tipo de busca: {escolha}</font> <br />"
  201.                      f"          <p> PS.: As imagens podem divergir na posição dos nodos"
  202.                      f" se comparado com a outra imagem. Entretanto, ambas correspondem ao mesmo grafo, apenas desenhado"
  203.                      f" de uma forma diferente. </p>"
  204.                      f"          <p> Grafo completo: </p>"
  205.                      f"          <img src={g1}>"
  206.                      f"          <p> Grafo com o inicio e o alvo de busca selecionados: Inicio:{dicionario.get(path[0])}"
  207.                      f" final: {dicionario.get(path[len(path) - 1])}</p>"
  208.                      f"          <img src={g3}>"
  209.                      f"          <p> Grafo com Caminho definido -> Rota do caminho> {rota}: </p>"
  210.                      f"          <img src={g2}>"  
  211.                      f"     </body>"
  212.                      f"</html>")
  213. saidaHtml.close()
Advertisement
Add Comment
Please, Sign In to add comment