{"id":23953,"date":"2023-09-10T11:29:25","date_gmt":"2023-09-10T14:29:25","guid":{"rendered":"https:\/\/maurinsoft.com.br\/?p=23953"},"modified":"2023-09-11T10:01:07","modified_gmt":"2023-09-11T13:01:07","slug":"grafos-teoria-e-pratica","status":"publish","type":"post","link":"https:\/\/maurinsoft.com.br\/wp\/grafos-teoria-e-pratica\/","title":{"rendered":"Grafos Teoria e Pr\u00e1tica"},"content":{"rendered":"\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Parte do material deste tutorial veio do CHATGPT4.<\/p>\n<\/blockquote>\n\n\n\n<h1 class=\"wp-block-heading\">Origem<\/h1>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"339\" height=\"180\" src=\"https:\/\/maurinsoft.com.br\/wp-content\/uploads\/2023\/09\/image-9.png\" alt=\"\" class=\"wp-image-23954\" srcset=\"https:\/\/maurinsoft.com.br\/wp\/wp-content\/uploads\/2023\/09\/image-9.png 339w, https:\/\/maurinsoft.com.br\/wp\/wp-content\/uploads\/2023\/09\/image-9-300x159.png 300w\" sizes=\"auto, (max-width: 339px) 100vw, 339px\" \/><\/figure>\n<\/div>\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problema das Pontes de K\u00f6nigsberg (1736)<\/strong>: Leonhard Euler demonstrou ser imposs\u00edvel caminhar pela cidade de K\u00f6nigsberg, passando por cada uma das sete pontes exatamente uma vez e retornando ao ponto de partida. Este problema \u00e9 a origem da teoria dos grafos.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>grafo = {\n    \"A\": &#91;\"B\", \"C\"],\n    \"B\": &#91;\"A\", \"D\", \"E\"],\n    \"C\": &#91;\"A\", \"F\"],\n    \"D\": &#91;\"B\"],\n    \"E\": &#91;\"B\", \"F\"],\n    \"F\": &#91;\"C\", \"E\"]\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Desenvolvimento e Conceitos Chave<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Gustav Kirchhoff<\/strong>: Introduziu a matriz de incid\u00eancia e estudou \u00e1rvores abrangentes.<\/li>\n\n\n\n<li><strong>James Joseph Sylvester<\/strong>: Investigou grafos planares.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Teoremas e Problemas Not\u00e1veis<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Teorema das quatro cores<\/strong>: Qualquer mapa em um plano pode ser colorido com no m\u00e1ximo quatro cores distintas, de modo que regi\u00f5es adjacentes n\u00e3o tenham a mesma cor. Provado em 1976.<\/li>\n\n\n\n<li><strong>Problema do caixeiro-viajante<\/strong>: Busca o caminho mais curto que visita cada cidade exatamente uma vez, retornando \u00e0 origem.<\/li>\n\n\n\n<li><strong>Algoritmos de Dijkstra e Floyd-Warshall<\/strong>: Encontram caminhos mais curtos em grafos.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Aplica\u00e7\u00f5es Modernas<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>S\u00e9culo XXI<\/strong>: Uso extensivo da teoria dos grafos em redes sociais, internet das coisas e sistemas complexos.<\/li>\n<\/ul>\n\n\n\n<p>Essa s\u00edntese destaca os marcos e conceitos mais relevantes na evolu\u00e7\u00e3o da teoria dos grafos.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Elementos dos Grafos<\/h1>\n\n\n\n<p>Os grafos s\u00e3o rela\u00e7\u00f5es entre partes, e podemos entender seus elementos como se segue:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Elementos B\u00e1sicos de Grafos<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>V\u00e9rtices (ou N\u00f3s)<\/strong>: S\u00e3o as entidades do grafo. Em contextos pr\u00e1ticos, podem representar cidades, computadores em uma rede, pessoas em uma rede social, entre outros.<\/li>\n\n\n\n<li><strong>Arestas (ou Liga\u00e7\u00f5es)<\/strong>: S\u00e3o as conex\u00f5es entre os v\u00e9rtices. Em um mapa, por exemplo, uma aresta pode representar uma estrada conectando duas cidades.<\/li>\n\n\n\n<li><strong>Grafos Dirigidos vs. N\u00e3o Dirigidos<\/strong>: Em um grafo dirigido (ou digrafo), as arestas t\u00eam uma dire\u00e7\u00e3o, indo de um v\u00e9rtice para outro. Em grafos n\u00e3o dirigidos, as arestas n\u00e3o t\u00eam dire\u00e7\u00e3o.<\/li>\n\n\n\n<li><strong>Peso<\/strong>: As arestas podem ter um peso associado, que pode representar dist\u00e2ncias, custos, etc.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Implementa\u00e7\u00f5es<\/h2>\n\n\n\n<p>A implementa\u00e7\u00e3o de um grafo pode ser feita de v\u00e1rias formas, pois \u00e9 um conceito.<\/p>\n\n\n\n<p>Porem as formas mais comuns s\u00e3o descritos a seguir:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Lista de Adjac\u00eancia<\/strong><\/h3>\n\n\n\n<p>\u00c9 uma lista onde, para cada v\u00e9rtice do grafo, armazenamos uma lista de seus v\u00e9rtices adjacentes. \u00c9 uma forma eficiente de armazenar grafos esparso.<\/p>\n\n\n\n<p>Exemplo em python:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Matriz de Adjac\u00eancia<\/strong><\/h3>\n\n\n\n<p>A matriz de adjac\u00eancia \u00e9 uma das formas mais comuns de representar um grafo em termos de estrutura de dados. Ela utiliza uma matriz bidimensional (um array de arrays) para expressar as rela\u00e7\u00f5es entre os v\u00e9rtices de um grafo.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Caracter\u00edsticas B\u00e1sicas<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Tamanho da Matriz<\/strong>: Se um grafo tem <em>V<\/em> v\u00e9rtices, sua matriz de adjac\u00eancia ser\u00e1 de tamanho <em>V<\/em>\u00d7<em>V<\/em>.<\/li>\n\n\n\n<li><strong>Grafos N\u00e3o Dirigidos<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Se o v\u00e9rtice <em>i<\/em> estiver conectado ao v\u00e9rtice <em>j<\/em>, ent\u00e3o matriz[i][j] = 1 (ou o peso da aresta, em grafos ponderados).<\/li>\n\n\n\n<li>Como o grafo \u00e9 n\u00e3o dirigido, matriz[j][i] tamb\u00e9m ser\u00e1 1.<\/li>\n\n\n\n<li>Em outras palavras, a matriz \u00e9 sim\u00e9trica em rela\u00e7\u00e3o \u00e0 sua diagonal principal.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Grafos Dirigidos (Digrafos)<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Se existir uma aresta dirigida do v\u00e9rtice <em>i<\/em> para o v\u00e9rtice <em>j<\/em>, ent\u00e3o matriz[i][j] = 1 (ou o peso da aresta).<\/li>\n\n\n\n<li>Neste caso, a matriz n\u00e3o \u00e9 necessariamente sim\u00e9trica.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Grafos Ponderados<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Em vez de conter apenas valores bin\u00e1rios (0 ou 1), a matriz cont\u00e9m os pesos das arestas. Se n\u00e3o houver conex\u00e3o entre dois v\u00e9rtices, um valor padr\u00e3o (geralmente 0 ou infinito) \u00e9 usado.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Diagonal Principal<\/strong>: Em muitos grafos, a diagonal principal (matriz[i][i] para todos os <em>i<\/em>) cont\u00e9m zeros, porque muitos grafos n\u00e3o t\u00eam la\u00e7os (uma aresta que conecta um v\u00e9rtice a si mesmo). Se o grafo permitir la\u00e7os, o valor na diagonal principal representar\u00e1 a presen\u00e7a (ou o peso) de tal la\u00e7o.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Vantagens e Desvantagens da Matriz de Adjac\u00eancia<\/h3>\n\n\n\n<p><strong>Vantagens<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Acesso direto: A verifica\u00e7\u00e3o da exist\u00eancia de uma aresta entre dois v\u00e9rtices \u00e9 realizada em tempo constante.<\/li>\n\n\n\n<li>Representa\u00e7\u00e3o intuitiva: \u00c9 f\u00e1cil visualizar e entender, especialmente para grafos pequenos.<\/li>\n<\/ul>\n\n\n\n<p><strong>Desvantagens<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Uso de espa\u00e7o: Para um grafo com <em>V<\/em> v\u00e9rtices, \u00e9 necess\u00e1rio <em>V\u00b2<\/em> espa\u00e7o, o que pode ser ineficiente para grafos grandes e esparsos.<\/li>\n\n\n\n<li>Iterar sobre os vizinhos: Em um grafo esparso, descobrir os vizinhos de um v\u00e9rtice exige que se verifique toda uma linha ou coluna, o que pode ser ineficiente.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Exemplo<\/h3>\n\n\n\n<p>Para o grafo com v\u00e9rtices <em>A<\/em>,<em>B<\/em>,<em>C<\/em> e arestas (<em>A<\/em>,<em>B<\/em>),(<em>B<\/em>,<em>C<\/em>):<\/p>\n\n\n\n<p>A matriz de adjac\u00eancia (n\u00e3o ponderada) seria:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>   A  B  C\nA &#91;0, 1, 0]\nB &#91;1, 0, 1]\nC &#91;0, 1, 0]<\/code><\/pre>\n\n\n\n<p>Se este fosse um grafo ponderado, onde a aresta (<em>A<\/em>,<em>B<\/em>) tem peso 3 e (<em>B<\/em>,<em>C<\/em>) tem peso 2, a matriz seria:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>   A  B  C\nA &#91;0, 3, 0]\nB &#91;3, 0, 2]\nC &#91;0, 2, 0]\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Exemplo de Solu\u00e7\u00e3o de Problema de Rota<\/h2>\n\n\n\n<p>Apresentaremos um problema de Rota, onde teremos apenas 5 pontes para ir do ponto A ao ponto C.<\/p>\n\n\n\n<p>Nele apresentaremos uma proposta descritiva e depois uma proposta em Python.<\/p>\n\n\n\n<p>Vamos ao grafo dado:<\/p>\n\n\n\n<p>V\u00e9rtices:<em>A<\/em>,<em>B<\/em>,<em>C<\/em>,<em>D<\/em>,<em>E<\/em> Liga\u00e7\u00f5es: <em>A<\/em>\u2212<em>B<\/em>,<em>B<\/em>\u2212<em>E<\/em>,<em>E<\/em>\u2212<em>C<\/em>,<em>D<\/em>\u2212<em>A<\/em>,<em>B<\/em>\u2212<em>C<\/em><\/p>\n\n\n\n<p>A matriz de adjac\u00eancia \u00e9 uma matriz <em>n<\/em>\u00d7<em>n<\/em> onde <em>n<\/em> \u00e9 o n\u00famero de v\u00e9rtices. A entrada <em>M(<\/em><em>i,j)<\/em>\u200b ser\u00e1 1 se o v\u00e9rtice <em>i<\/em> estiver ligado ao v\u00e9rtice <em>j<\/em> e 0 caso contr\u00e1rio.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"638\" height=\"479\" src=\"https:\/\/maurinsoft.com.br\/wp-content\/uploads\/2023\/09\/image-10.png\" alt=\"\" class=\"wp-image-23955\" srcset=\"https:\/\/maurinsoft.com.br\/wp\/wp-content\/uploads\/2023\/09\/image-10.png 638w, https:\/\/maurinsoft.com.br\/wp\/wp-content\/uploads\/2023\/09\/image-10-600x450.png 600w, https:\/\/maurinsoft.com.br\/wp\/wp-content\/uploads\/2023\/09\/image-10-300x225.png 300w\" sizes=\"auto, (max-width: 638px) 100vw, 638px\" \/><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\">Resolvendo o problema com python<\/h2>\n\n\n\n<p>Uma maneira simples de fazer isso \u00e9 usando uma busca em largura (BFS). Vamos criar um exemplo em Python para isso:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import heapq\n\ndef heuristic(node, goal):\n    # Como um grafo n\u00e3o possui coordenadas espaciais, podemos usar uma heur\u00edstica trivial.\n    return 0\n\ndef a_star(graph, start, goal):\n    open_list = &#91;(0, start)]\n    g_costs = {node: float('inf') for node in range(len(graph))}\n    g_costs&#91;start] = 0\n\n    came_from = {}\n\n    while open_list:\n        current_cost, current_node = heapq.heappop(open_list)\n\n        if current_node == goal:\n            path = &#91;]\n            while current_node in came_from:\n                path.insert(0, current_node)\n                current_node = came_from&#91;current_node]\n            path.insert(0, start)\n            return path\n\n        for neighbor, cost in enumerate(graph&#91;current_node]):\n            if cost == 1:  # Existe uma aresta\n                tentative_g_cost = g_costs&#91;current_node] + 1\n                if tentative_g_cost &lt; g_costs&#91;neighbor]:\n                    came_from&#91;neighbor] = current_node\n                    g_costs&#91;neighbor] = tentative_g_cost\n                    f_cost = tentative_g_cost + heuristic(neighbor, goal)\n                    heapq.heappush(open_list, (f_cost, neighbor))\n\n    return None\n\ngraph = &#91;\n    &#91;0, 1, 0, 1, 0],  # A\n    &#91;1, 0, 1, 0, 1],  # B\n    &#91;0, 1, 0, 0, 1],  # C\n    &#91;1, 0, 0, 0, 0],  # D\n    &#91;0, 1, 1, 0, 0]   # E\n]\n\npath = a_star(graph, 0, 2)\nif path:\n    print(\" -&gt; \".join(chr(65 + node) for node in path))\nelse:\n    print(\"N\u00e3o foi encontrado um caminho de A para C.\")<\/code><\/pre>\n\n\n\n<p><strong>Resultado:<\/strong><\/p>\n\n\n\n<p>A -&gt; B -&gt; C<\/p>\n\n\n\n<p>Outros usos de Grafo:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Outro problema complexo<\/h2>\n\n\n\n<p>Agora teremos como objetivo desenvolver um NLP que ir\u00e1 analisar de comandos dados de forma textual, utilizando grafos como base de tomada de decis\u00e3o.<\/p>\n\n\n\n<p>Para isso temos duas tabelas:<\/p>\n\n\n\n<p><strong>Palavras<\/strong>: Contem uma lista de palavras usadas nos textos.<\/p>\n\n\n\n<p><strong>Comandos<\/strong>: Contem uma lista de comandos poss\u00edveis.<\/p>\n\n\n\n<p>Usaremos como exemplo de v\u00e9rtice apenas quando duas palavras em sequencia estiverem atendidas em determinado grafo, ai ligaremos estes aos comandos.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Tabela Palavras:<\/h3>\n\n\n\n<p>Esta tabela cont\u00e9m uma lista de palavras chave que podem ser usadas para determinar a\u00e7\u00f5es.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Palavras<\/th><\/tr><\/thead><tbody><tr><td>Grave<\/td><\/tr><tr><td>Di\u00e1rio<\/td><\/tr><tr><td>Reproduza<\/td><\/tr><tr><td>M\u00fasica<\/td><\/tr><tr><td>Ligue<\/td><\/tr><tr><td>Luz<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Tabela A\u00e7\u00f5es:<\/h3>\n\n\n\n<p>Esta tabela associa sequ\u00eancias de palavras a a\u00e7\u00f5es espec\u00edficas.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Sequ\u00eancia de Palavras<\/th><th>A\u00e7\u00e3o<\/th><\/tr><\/thead><tbody><tr><td>Grave Di\u00e1rio<\/td><td>Grava\u00e7\u00e3o de entradas no di\u00e1rio<\/td><\/tr><tr><td>Reproduza M\u00fasica<\/td><td>Tocar m\u00fasica<\/td><\/tr><tr><td>Ligue Luz<\/td><td>Acender a luz<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Neste caso, o grafo seria algo assim:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>O v\u00e9rtice &#8220;Grave&#8221; tem uma aresta direcionada para &#8220;Di\u00e1rio&#8221;, que representa a a\u00e7\u00e3o &#8220;Grava\u00e7\u00e3o de entradas no di\u00e1rio&#8221;.<\/li>\n\n\n\n<li>O v\u00e9rtice &#8220;Reproduza&#8221; tem uma aresta direcionada para &#8220;M\u00fasica&#8221;, representando a a\u00e7\u00e3o &#8220;Tocar m\u00fasica&#8221;.<\/li>\n\n\n\n<li>O v\u00e9rtice &#8220;Ligue&#8221; tem uma aresta direcionada para &#8220;Luz&#8221;, representando a a\u00e7\u00e3o &#8220;Acender a luz&#8221;.<\/li>\n<\/ol>\n\n\n\n<p>A ideia aqui \u00e9 que, se algu\u00e9m dissesse &#8220;Grave meu Di\u00e1rio&#8221;, o sistema reconheceria a sequ\u00eancia &#8220;Grave Di\u00e1rio&#8221; e acionaria a fun\u00e7\u00e3o correspondente de &#8220;Grava\u00e7\u00e3o de entradas no di\u00e1rio&#8221;. As stop words, como &#8220;meu&#8221;, seriam ignoradas pelo sistema.<\/p>\n\n\n\n<p>Para implementar isso, voc\u00ea poderia criar um dicion\u00e1rio em Python que mapeia sequ\u00eancias de palavras (arestas) a a\u00e7\u00f5es, e ent\u00e3o usar esse dicion\u00e1rio para determinar a a\u00e7\u00e3o apropriada com base na entrada do usu\u00e1rio.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Passos:<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Instalar as bibliotecas necess\u00e1rias<\/li>\n\n\n\n<li>Configurar o banco de dados<\/li>\n\n\n\n<li>Criar a tabela de arestas no banco de dados<\/li>\n\n\n\n<li>Implementar fun\u00e7\u00f5es em Python para interagir com o banco de dados<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">1. Instalar as bibliotecas necess\u00e1rias<\/h3>\n\n\n\n<p>Certifique-se de que voc\u00ea tem o MySQL instalado e em execu\u00e7\u00e3o. Depois, voc\u00ea pode instalar o conector MySQL para Python:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pip install mysql-connector-python\npip install nltk\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2. Configurar o banco de dados<\/h3>\n\n\n\n<p>Crie um novo banco de dados chamado <code>graph_db<\/code> e um usu\u00e1rio para esse banco de dados. Voc\u00ea pode fazer isso usando a interface de linha de comando do MySQL ou um cliente GUI como o MySQL Workbench.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cria\u00e7\u00e3o do Banco<\/h2>\n\n\n\n<p>Aqui est\u00e1 uma sugest\u00e3o de estrutura:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><code>words<\/code>: Guarda os v\u00e9rtices do tipo palavra.<\/li>\n\n\n\n<li><code>commands<\/code>: Guarda os v\u00e9rtices do tipo comando.<\/li>\n\n\n\n<li><code>edges<\/code>: Guarda as arestas, referenciando palavras e comandos.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">SQL para cria\u00e7\u00e3o das tabelas:<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE DATABASE graph_db;\nUSE graph_db;\n\n-- Tabela de palavras\nCREATE TABLE words (\n    word_id INT AUTO_INCREMENT PRIMARY KEY,\n    word_name VARCHAR(50) UNIQUE NOT NULL\n);\n\n-- Tabela de comandos\nCREATE TABLE commands (\n    command_id INT AUTO_INCREMENT PRIMARY KEY,\n    command_name VARCHAR(50) UNIQUE NOT NULL\n);\n\n-- Tabela de arestas\nCREATE TABLE edges (\n    edge_id INT AUTO_INCREMENT PRIMARY KEY,\n    word_id1 INT,\n    word_id2 INT,\n    command_id INT,\n    FOREIGN KEY (word_id1) REFERENCES words(word_id),\n    FOREIGN KEY (word_id2) REFERENCES words(word_id),\n    FOREIGN KEY (command_id) REFERENCES commands(command_id)\n);\n<\/code><\/pre>\n\n\n\n<p>Nesta estrutura:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A tabela <code>words<\/code> tem um ID \u00fanico para cada palavra e um nome que \u00e9 exclusivo.<\/li>\n\n\n\n<li>A tabela <code>commands<\/code> tem um ID \u00fanico para cada comando e um nome que \u00e9 exclusivo.<\/li>\n\n\n\n<li>A tabela <code>edges<\/code> tem um ID \u00fanico para cada aresta. As colunas <code>word_id<\/code> e <code>command_id<\/code> s\u00e3o chaves estrangeiras que apontam para os IDs nas tabelas <code>words<\/code> e <code>commands<\/code>, respectivamente.<\/li>\n<\/ul>\n\n\n\n<p>Com essa estrutura, a tabela <code>edges<\/code> representa as rela\u00e7\u00f5es entre palavras e comandos. Isso significa que cada entrada (linha) na tabela <code>edges<\/code> \u00e9 uma rela\u00e7\u00e3o entre uma palavra espec\u00edfica na tabela <code>words<\/code> e um comando espec\u00edfico na tabela <code>commands<\/code>.<\/p>\n\n\n\n<p>Configurando aplica\u00e7\u00e3o e Banco de dados<\/p>\n\n\n\n<p>Iremos primeiramente criar as ferramentas basicas para cadastrar as informa\u00e7\u00f5es e o ambiente.<\/p>\n\n\n\n<p>Ent\u00e3o temos a conex\u00e3o com o banco de dados.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import mysql.connector\nimport nltk\nnltk.download(\"stopwords\")\nfrom nltk.corpus import stopwords\n\n\nstop_words = set(stopwords.words('portuguese'))\n\n# Configura\u00e7\u00e3o da conex\u00e3o com o banco\nDB_CONFIG = {\n    \"host\": \"localhost\",\n    \"user\": \"your_username\",\n    \"password\": \"your_password\",\n    \"database\": \"graph_db\"\n}\n\n\"\"\"Cria arestas com base em frases de exemplo.\"\"\"\nfrases = &#91;\n        \"Comece a grava\u00e7\u00e3o de \u00e1udio\",\n        \"Salve esse texto importante\",\n        \"Defina um alerta para amanh\u00e3\",\n        \"Quero a grava\u00e7\u00e3o dessa reuni\u00e3o\",\n        \"Salve a anota\u00e7\u00e3o rapidamente\"\n]\n\ncomandos = &#91;\n        \"Iniciar grava\u00e7\u00e3o\",\n        \"Salvar texto\",\n        \"Configurar alerta\",\n        \"Iniciar grava\u00e7\u00e3o\",\n        \"Salvar anota\u00e7\u00e3o\"\n]\n\n<\/code><\/pre>\n\n\n\n<p>Criaremos a fun\u00e7\u00e3o de criar a conex\u00e3o:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def connect_to_database():\n    \"\"\"Retorna uma conex\u00e3o com o banco de dados.\"\"\"\n    return mysql.connector.connect(**DB_CONFIG)<\/code><\/pre>\n\n\n\n<p>Criamos agora a fun\u00e7\u00e3o de pegar o ID:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def get_id(name, table):\n    \"\"\"Busca o ID de um item pelo nome, na tabela especificada.\"\"\"\n    connection = connect_to_database()\n    cursor = connection.cursor()\n    \n    column = \"word_name\" if table == \"words\" else \"command_name\"\n    query = f\"SELECT * FROM {table} WHERE {column}=%s\"\n    cursor.execute(query, (name,))\n    result = cursor.fetchone()\n    \n    cursor.close()\n    connection.close()\n    \n    return result&#91;0] if result else None<\/code><\/pre>\n\n\n\n<p>Agora criamos a fun\u00e7\u00e3o que popula as arestas:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def populaArestas(word1, word2, command):\n    \"\"\"Popula a tabela edges com as rela\u00e7\u00f5es entre palavras e comando.\"\"\"\n    connection = connect_to_database()\n    cursor = connection.cursor()\n    \n    word1_id = get_id(word1, 'words')\n    word2_id = get_id(word2, 'words')\n    command_id = get_id(command, 'commands')\n    \n    if not word1_id or not word2_id or not command_id:\n        print(f\"Erro: Palavras ou comando n\u00e3o encontrados: '{word1}', '{word2}', '{command}'\")\n        return\n    \n    insert_query = \"INSERT INTO edges (word_id, command_id) VALUES (%s, %s)\"\n    \n    # Inserindo rela\u00e7\u00e3o da primeira palavra com o comando\n    cursor.execute(insert_query, (word1_id, command_id))\n    \n    # Inserindo rela\u00e7\u00e3o da segunda palavra com o comando\n    cursor.execute(insert_query, (word2_id, command_id))\n    \n    connection.commit()\n    cursor.close()\n    connection.close()<\/code><\/pre>\n\n\n\n<p>Agora iremos criar os nossos comandos, para isso temos duas fun\u00e7\u00f5es:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>CadastraCMD que cria o registro de comandos.<\/li>\n\n\n\n<li>ExemploCMD que monta os exemplos que iremos usar.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>def cadastreCMD(command_name):\n    \"\"\"Cadastra um novo comando na tabela commands.\"\"\"\n    connection = connect_to_database()\n    cursor = connection.cursor()\n    \n    insert_query = \"INSERT INTO commands (command_name) VALUES (%s)\"\n    \n    try:\n        cursor.execute(insert_query, (command_name,))\n        connection.commit()\n    except mysql.connector.Error as err:\n        print(f\"Erro ao inserir comando '{command_name}': {err}\")\n    \n    cursor.close()\n    connection.close()\n\ndef ExemploCMD():   \n    for cmd in comandos:\n        cadastreCMD(cmd)<\/code><\/pre>\n\n\n\n<p>Agora iremos cadastrar nossas palavras, para isso iremos usar o exemplo a seguir:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>CadastraWords &#8211; Cadastra a lista de palavras avaliadas nos textos<\/li>\n\n\n\n<li>ExemploWords &#8211; Lista as frases, criando as palavras.<\/li>\n<\/ul>\n\n\n\n<p>Ser\u00e3o implementadas da seguinte forma:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def CadastraWords(word_name):\n    \"\"\"Cadastra uma nova palavra na tabela words.\"\"\"\n    connection = connect_to_database()\n    cursor = connection.cursor()\n    \n    insert_query = \"INSERT INTO words (word_name) VALUES (%s)\"\n    \n    try:\n        cursor.execute(insert_query, (word_name,))\n        connection.commit()\n    except mysql.connector.Error as err:\n        print(f\"Erro ao inserir palavra '{word_name}': {err}\")\n    \n    cursor.close()\n    connection.close()\n\n\ndef ExemploWords():\n  for frase in frases:\n        palavras = frase.split() # Separa a frase em palavras individuais\n        for palavra in palavras:\n            # Ignoramos palavras muito comuns (stop words) e n\u00fameros\n            if palavra.lower() not in stop_words and not palavra.isnumeric():\n                CadastraWords(palavra)<\/code><\/pre>\n\n\n\n<p>Agora iremos criar a fun\u00e7\u00e3o:<\/p>\n\n\n\n<p>get_id_from_Table &#8211; Retorna o ID de uma dado valor de uma dada tabela para uma dada coluna.<\/p>\n\n\n\n<p><strong>CriaArestas <\/strong>&#8211; Cria a tabela de relacionamento (grafo) de Palavras.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def get_id_words(value, column_name):\n    \"\"\"Retorna o ID associado a um valor em uma coluna e tabela espec\u00edficos.\"\"\"\n    connection = connect_to_database()\n    cursor = connection.cursor()\n\n    select_query = f\"SELECT word_id FROM words WHERE {column_name} = %s\"\n    cursor.execute(select_query, (value,))\n\n    result = cursor.fetchone()\n    cursor.close()\n    connection.close()\n\n    return result&#91;0] if result else None\n\ndef get_id_commands(value, column_name):\n    \"\"\"Retorna o ID associado a um valor em uma coluna e tabela espec\u00edficos.\"\"\"\n    connection = connect_to_database()\n    cursor = connection.cursor()\n\n    select_query = f\"SELECT command_id FROM commands WHERE {column_name} = %s\"\n    cursor.execute(select_query, (value,))\n\n    result = cursor.fetchone()\n    cursor.close()\n    connection.close()\n\n    return result&#91;0] if result else None\n\ndef CriaArestas(Word1, Word2, Cmd):\n    print(Word1)\n    print(Word2)\n    \"\"\"Cria uma aresta associando Word1 e Word2 ao comando Cmd.\"\"\"\n    word1_id = get_id_words(Word1, \"word_name\")\n    word2_id = get_id_words(Word2, \"word_name\")\n    cmd_id = get_id_commands(Cmd,  \"command_name\")\n\n    print(word1_id);\n    print(word2_id);\n    print(cmd_id);\n\n    if not word1_id or not word2_id or not cmd_id:\n        print(\"Erro: Um ou mais valores n\u00e3o foram encontrados no banco de dados.\")\n        return\n\n    connection = connect_to_database()\n    cursor = connection.cursor()\n    \n    insert_query = \"\"\"\n    INSERT INTO edges (word_id1, word_id2, command_id)\n    VALUES (%s, %s, %s)\n    \"\"\"\n    \n    try:\n        cursor.execute(insert_query, (word1_id, word2_id, cmd_id))\n        connection.commit()\n    except mysql.connector.Error as err:\n        print(f\"Erro ao inserir aresta: {err}\")\n    \n    cursor.close()\n    connection.close()<\/code><\/pre>\n\n\n\n<p>Agora iremos povoar as arestas. Para isso usaremos a fun\u00e7\u00e3o:<\/p>\n\n\n\n<p><code>ExemploAresta<\/code> &#8211; Faz o cadastro das arestas baseado nas stop-words e palavras n\u00e3o num\u00e9ricas.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def ExemploAresta():\n    for index, frase in enumerate(frases):\n        palavras = &#91;palavra for palavra in frase.split() if palavra.lower() not in stop_words and not palavra.isnumeric()]\n        \n        for i in range(len(palavras) - 1):\n            # Criamos arestas entre palavras sequenciais e associamos a um comando\n            CriaArestas(palavras&#91;i], palavras&#91;i+1], comandos&#91;index])\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Juntando tudo<\/h2>\n\n\n\n<p>Neste c\u00f3digo podemos ver onde tudo se encaixa.<\/p>\n\n\n\n<p>Onde criamos os exemplos, e finalizamos o cadastro.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>connect_to_database()\n\nExemploWords();\n\nExemploCMD();\n\nExemploAresta();<\/code><\/pre>\n\n\n\n<p>Aqui disponibilizo o arquivo do grafo, j\u00e1 montado.<\/p>\n\n\n\n<p>GITHUB:<\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/marcelomaurin\/grafo01\">https:\/\/github.com\/marcelomaurin\/grafo01<\/a><\/p>\n\n\n\n<p>No pr\u00f3ximo post iremos apresentar a conclus\u00e3o com o projeto montado o sistema de busca, onde faremos conclus\u00f5es e testes no projeto.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Parte do material deste tutorial veio do CHATGPT4. Origem Desenvolvimento e Conceitos Chave Teoremas e Problemas Not\u00e1veis Aplica\u00e7\u00f5es Modernas Essa s\u00edntese destaca os marcos e conceitos mais relevantes na evolu\u00e7\u00e3o da teoria dos grafos. Elementos dos Grafos Os grafos s\u00e3o rela\u00e7\u00f5es entre partes, e podemos entender seus elementos como se segue: Elementos B\u00e1sicos de Grafos [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":23954,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[39,51],"tags":[503,504,231,339],"class_list":["post-23953","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ia","category-python","tag-grafo","tag-grafos","tag-ia","tag-python"],"_links":{"self":[{"href":"https:\/\/maurinsoft.com.br\/wp\/wp-json\/wp\/v2\/posts\/23953","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/maurinsoft.com.br\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/maurinsoft.com.br\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/maurinsoft.com.br\/wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/maurinsoft.com.br\/wp\/wp-json\/wp\/v2\/comments?post=23953"}],"version-history":[{"count":23,"href":"https:\/\/maurinsoft.com.br\/wp\/wp-json\/wp\/v2\/posts\/23953\/revisions"}],"predecessor-version":[{"id":24025,"href":"https:\/\/maurinsoft.com.br\/wp\/wp-json\/wp\/v2\/posts\/23953\/revisions\/24025"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/maurinsoft.com.br\/wp\/wp-json\/wp\/v2\/media\/23954"}],"wp:attachment":[{"href":"https:\/\/maurinsoft.com.br\/wp\/wp-json\/wp\/v2\/media?parent=23953"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/maurinsoft.com.br\/wp\/wp-json\/wp\/v2\/categories?post=23953"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/maurinsoft.com.br\/wp\/wp-json\/wp\/v2\/tags?post=23953"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}