├── .github ├── ISSUE_TEMPLATE │ ├── discuss-o.md │ ├── feature.md │ └── reporte-o-bug.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── Main.py ├── README-en.md ├── README.md ├── __init__.py ├── __tests__ ├── __init__.py ├── test_graph.py └── test_simple_graph.py ├── docs ├── _config.yml ├── edges │ ├── simple_edge.md │ └── weighted_edge.md ├── graphs │ ├── complete_graph.md │ ├── graph.md │ ├── simple_graph.md │ └── weighted_graph.md ├── index.md ├── start.md └── vertices │ └── simple_vertex.md ├── poetry.lock ├── py_graph_t ├── CompleteGraph.py ├── Graph.py ├── SimpleGraph.py ├── __init__.py ├── edges │ ├── SimpleEdge.py │ └── __init__.py ├── exceptions │ ├── SimpleGraphException.py │ └── __init__.py ├── util │ ├── ValueBinding.py │ └── __init__.py └── vertex │ ├── SimpleVertex.py │ └── __init__.py ├── pyproject.toml ├── setup.cfg └── setup.py /.github/ISSUE_TEMPLATE/discuss-o.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: DISCUSSÃO 3 | about: Inicia uma discussão sobre um determinado assunto. 4 | title: Discussão 5 | labels: question 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Descrição da discussão:** 11 | Aqui você descreve o assunto que irá ser discutido nessa issue. 12 | 13 | **Necessidade:** 14 | Aqui você pode explicar porquê essa discussão é necessária. 15 | 16 | **Seu ponto de vista:** 17 | Aqui você pode dar seu ponto de vista e mostrar os pontos que você considerou importantes para a sua decisão. 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: FEATURE 3 | about: Sugira uma ideia para esse projeto 4 | title: Feature 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Descrição da feature:** 11 | Aqui você descreve o que irá mudar com sua feature. 12 | 13 | **Necessidade:** 14 | Aqui você descreve o porquê de sua feature é necessária. 15 | 16 | **Implementação:** 17 | Aqui você pode dar ideias de implementações para sua feature. 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/reporte-o-bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: BUG 3 | about: Crie um relatório para nos ajudar 4 | title: Bug 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Descrição do bug** 11 | Uma descrição clara e concisa do que é o bug. 12 | 13 | **Reproduzir o bug** 14 | Etapas para reproduzir o bug: 15 | 1. 16 | 2. 17 | 3. 18 | 19 | **Comportamento esperado** 20 | Uma descrição clara e concisa do que você acha que deveria acontecer. 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: PR 3 | about: Abrir uma Pull Request 4 | title: PR 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | #Numero_da_issue 11 | 12 | **Descrição do bug/feature:** 13 | 14 | 15 | **Solução** 16 | 17 | 18 | **Coisas a serem feitas** 19 | 20 | 21 | 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # VSCode 10 | .vscode/ 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | MANIFEST 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | 53 | # Translations 54 | *.mo 55 | *.pot 56 | 57 | # Django stuff: 58 | *.log 59 | local_settings.py 60 | db.sqlite3 61 | 62 | # Flask stuff: 63 | instance/ 64 | .webassets-cache 65 | 66 | # Scrapy stuff: 67 | .scrapy 68 | 69 | # Sphinx documentation 70 | docs/_build/ 71 | 72 | # PyBuilder 73 | target/ 74 | 75 | # Jupyter Notebook 76 | .ipynb_checkpoints 77 | 78 | # pyenv 79 | .python-version 80 | 81 | # celery beat schedule file 82 | celerybeat-schedule 83 | 84 | # SageMath parsed files 85 | *.sage.py 86 | 87 | # Environments 88 | .env 89 | .venv 90 | env/ 91 | venv/ 92 | ENV/ 93 | env.bak/ 94 | venv.bak/ 95 | 96 | # Spyder project settings 97 | .spyderproject 98 | .spyproject 99 | 100 | # Rope project settings 101 | .ropeproject 102 | 103 | # mkdocs documentation 104 | /site 105 | 106 | # mypy 107 | .mypy_cache/ 108 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.8" 4 | 5 | before_install: 6 | - pip install poetry 7 | # command to install dependencies 8 | install: 9 | - poetry install -v 10 | # command to run tests 11 | script: 12 | - poetry run pycodestyle . 13 | - poetry run pytest -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | > Pode contribuir a vontade, você será sempre bem-vindo(a). Mas temos algumas regras para serem seguidas. 3 | 4 | ## Adicionar/Atualizar funcionalidades 5 | 6 | Você olhou a aplicação e pensou em alguma funcionalidade que deveria ser adicionada no projeto ? :open_mouth: 7 | 8 | ***Então, você tem duas opções:*** 9 | 10 | - [Abrir uma issue detalhando sua ideia](#criando-uma-issue) 11 | - [Você mesmo implementar a funcionalidade](#contribuir-com-implementação) 12 | 13 | ## Criando uma issue 14 | 15 | Na página do [projeto](https://github.com/Rickecr/PyGraph), você pode clicar no botão `Issues` e na página irá aparecer um botão `new issue`, então é só selecionar e seguir os seguintes passos: 16 | 17 | - Selecione o tipo da sua issue: `Bug ou Feature`. 18 | - Dê um bom nome a sua issue. 19 | - Detalhe bem sobre qual objetivo da issue. 20 | - Imagens caso possível. 21 | - Selecione labels para sua issue. 22 | - Por fim, clique em `Submit new issue`. 23 | 24 | ## Clonar o repositório 25 | 26 | Na página inicial do [repositório](https://github.com/Rickecr/PyGraph) tem um botão `Fork`. Ao clicar é só esperar concluir o fork. E então ele irá criar o repositório na sua conta. E agora é só clonar em sua máquina, assim: 27 | 28 | ```sh 29 | git clone https://github.com//PyGraph 30 | ``` 31 | 32 | Ao concluir, você terá o repositório em seu computador e então é só abrir em seu editor preferido e fazer suas modificações. 33 | 34 | Ao terminar suas modificações, você deve commitar suas alterações, mas primeiro: 35 | 36 | ```sh 37 | git add . 38 | ``` 39 | 40 | O comando acima irá preparar todos os arquivos modificados para serem commitados, passando por todas as alterações que foram feitas por você onde decedirá se a alteração será adicionada (você deve estar dentro da pasta do projeto para usar o comando). Agora é só commitar as alterações: 41 | 42 | ```sh 43 | git commit -m "" 44 | ``` 45 | 46 | E por fim, você irá enviar as alterações para o repositório remoto: 47 | 48 | ```sh 49 | git push origin master 50 | ``` 51 | 52 | Mas isso só irá alterar no seu fork, o repositório oficial não vai ter suas alterações e agora ? :confused: 53 | 54 | Calma, agora que entra o `Pull Request` ou `PR` 55 | 56 | ## Contribuir com implementação: 57 | 58 | Depois de ter realizado o fork e o clone do projeto, escolhido seu editor de texto favorito, nós amamos o VSCode, mas fique a vontade para escolher o seu. Então é hora de codar. 59 | 60 | Mas calma ai, antes de qualquer coisa, você deve **escolher uma issue** que pretender trabalhar. Se a issue que trata sobre a funcionalidade não existir, você deve criar e dizer que esta trabalhando nela, caso ela exista você deve dizer lá(caso não já tenha alguém) que pretende trabalhar na issue. E após feito isso, agora sim você está pronto para **codar**. 61 | 62 | ### Entendendo as pastas: 63 | 64 | O projeto se encontra na pasta `py_graph_t`, estamos aceitando dicas de nomes para biblioteca também :blush: . 65 | 66 | - Na pasta `edges` : Encontra-se todos os arquivos sobre arestas de um grafo, todas as implementações de uma aresta irão estar nessa pasta. Por exemplo, quando existir um grafo com arestas que possuem pesos, essa aresta será criada dentro dessa pasta, herdando da classe base de aresta(`SimpleEdge`). 67 | 68 | - Na pasta `vertex` : Encontra-se todos os arquivos sobre vértices de um grafo, todas as implementações de um vértice irão estar nessa pasta. Por exemplo, quando existir um grafo com vértices que possuem um dado a ser salvo, esse vértice será criado dentro dessa pasta, herdando da classe base de vértice(`SimpleVertex`). 69 | 70 | ### Como executar a aplicação: 71 | 72 | Nós usamos o poetry para gerenciar os pacotes. Portanto, antes de tudo precisamos instalá-lo. 73 | 74 | - Instalar o poetry: 75 | 76 | ~~~bash 77 | $ pip install --user poetry 78 | ~~~ 79 | 80 | - Para entrar em um shell dentro do seu ambiente virtual: 81 | 82 | ~~~bash 83 | $ poetry shell 84 | ~~~ 85 | 86 | - Instalar as dependências usadas no projeto: 87 | 88 | ~~~bash 89 | $ poetry install 90 | ~~~ 91 | 92 | Para mais detalhes do [poetry](https://python-poetry.org/docs/) 93 | 94 | **OBS:** Executar o comando acima dentro da pasta do projeto. 95 | 96 | - Agora você esta pronto para implementar sua funcionalidade/correção. 97 | 98 | ### Depois de implementar sua correção/funcionalidade: 99 | 100 | Muito bem. Agora só falta uma coisinha para abrir sua PR e ela ser aceita, **Testes**. Muita gente não gosta, nós sabemos, mas são eles que garantem que todo nosso código esteja funcionando. Assim facilitando muito a vida dos desenvolvedores. 101 | 102 | #### Testes: 103 | 104 | Para os testes nós optamos por usar o `pytest`, visto que é bem aceito pela comunidade Python e bastante fácil de usar. 105 | 106 | - Primeiro você precisa instalar o poetry: 107 | 108 | ~~~bash 109 | $ pip install --user poetry 110 | ~~~ 111 | 112 | - Para entrar em um shell dentro do seu ambiente virtual: 113 | 114 | ~~~bash 115 | $ poetry shell 116 | ~~~ 117 | 118 | - Para instalar as dependências usadas no projeto: 119 | 120 | ~~~bash 121 | $ poetry install 122 | ~~~ 123 | 124 | **OBS:** Os dois comandos acima só são necesśarios, caso ainda não tenha feito. 125 | 126 | - Para testar se tudo funcionou bem, digite no terminal: 127 | 128 | ~~~bash 129 | $ poetry run pytest --version 130 | ~~~ 131 | 132 | - Se a saída for a mesma que abaixo(podendo mudar a versão) esta tudo correto: 133 | 134 | ~~~bash 135 | $ This is pytest version 5.2.0, imported from /home/rickecr/.local/lib/python3.6/site-packages/pytest.py 136 | ~~~ 137 | 138 | - Para execução da suite de testes basta executar: 139 | 140 | ~~~bash 141 | $ poetry run pytest 142 | ~~~ 143 | 144 | - Para a execução dos testes no modo watch: 145 | 146 | ~~~bash 147 | $ poetry run ptw 148 | ~~~ 149 | 150 | 151 | E agora é só criar sua classe de teste, caso ela não exista para a classe que você fez a funcionalidade. 152 | Você deve criar os testes para a(s) sua(s) funcionalidade(s), tentando pegar todos os casos extremos, sabemos que é dificil também. 153 | 154 | E suas alterações devem garantir que os outros testes continuem funcionando, a não ser que você tenha achado um problema no código, algo que não deveria acontecer. 155 | 156 | E após realizar os testes, você está pronto para realizar sua [PR](https://github.com/Rickecr/PyGraph/blob/master/CONTRIBUTING.md#realizando-uma-pull-request---pr) e ser feliz com o mundo OpenSource. 157 | 158 | 159 | ### Entrando nos padrões: 160 | 161 | Nós optamos por seguir o padrão da [PEP 8](https://www.python.org/dev/peps/pep-0008/). Portanto, seu código não deve violar nenhuma regra da mesma. Para verificar isso, usamos o `pycodestyle`. 162 | 163 | #### Pycodestyle: 164 | 165 | Nós usamos o poetry para gerenciar nossas dependências. 166 | 167 | - Primeiro você precisa instalar o pipenv: 168 | 169 | ~~~bash 170 | $ pip install --user poetry 171 | ~~~ 172 | 173 | - Para instalar as dependências usadas no projeto: 174 | 175 | ~~~bash 176 | $ poetry install 177 | ~~~ 178 | 179 | **OBS:** Os dois comandos acima só são necesśarios, caso ainda não tenha feito. 180 | 181 | - Para executar o pycodestyle: 182 | 183 | ~~~bash 184 | poetry run pycodestyle . 185 | ~~~ 186 | 187 | ## Realizando uma Pull Request - PR 188 | 189 | Na página do seu fork irá aparecer uma mensagem em amarelo solicitando que você faça uma Pull Request para o repositório original. Ao clicar irá abrir uma página para você preencher as informações sobre sua PR. 190 | 191 | - Referencie a issue em que você está trabalhando usando `#` 192 | 193 | - Descreva suas modificações 194 | 195 | - Espere pela avaliação da sua PR, e pode ocorrer de pedimos algumas alterações a seres feitas 196 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Rich Ramalho 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Main.py: -------------------------------------------------------------------------------- 1 | from py_graph_t.Graph import Graph 2 | from py_graph_t.SimpleGraph import SimpleGraph 3 | -------------------------------------------------------------------------------- /README-en.md: -------------------------------------------------------------------------------- 1 | [![Open Source Helpers](https://www.codetriage.com/rickecr/pygraph/badges/users.svg)](https://www.codetriage.com/rickecr/pygraph) 2 | [![Build Status](https://travis-ci.org/Rickecr/PyGraph.svg?branch=master)](https://travis-ci.org/Rickecr/PyGraph) 3 | 4 | # PyGraph 5 | > This library has the purpose of implementing Graph Theory concepts. 6 | 7 | ## Objective: 8 | > The main objective is to implement most Graph Theory algorithms. 9 | 10 | - Practice the knowledge acquired in Graph Theory. 11 | - Facilitate the use of graph algorithms. 12 | 13 | ## Structure: 14 | > UML model of graph types that will be implemented: 15 | 16 | - Feel free to edit this UML template or make suggestions through issues. 17 | 18 | - [Template that can be edited by the community](https://www.lucidchart.com/invitations/accept/ac0a364a-2154-4e72-a333-4c9f2cc71629) 19 | 20 | ![Imgur](https://i.imgur.com/yq8A65S.jpg) 21 | 22 | ## How to contribute? :smiley: 23 | 24 | - PRs are accepted! 25 | - If you have thought of a nice feature or discovered a bug, and don't have time to code, open an issue. 26 | - We follow the [PEP 8](https://www.python.org/dev/peps/pep-0008/) guidelines. Therefore, before making a PR, make sure that your code complies with PEP 8 standards. 27 | - Always document your code. 28 | - For more information on how to contribute, take a look at [CONTRIBUTING.md](CONTRIBUTING.md). 29 | 30 | Feel free to submit suggestions, make changes and/or look for errors. Let us know by creating an issue or even correcting and submitting a PR. :relaxed: 31 | 32 | ## Do you want to contribute, but not with code? 33 | 34 | No problem, we have room for everyone. You don't need to code to help, you can contribute ideas, find problems, contribute to the documentation and/or make suggestions, etc. 35 | 36 | But if you want to code and get started here, you are very welcome, we are all here to learn. 37 | 38 | ## Hall of Fame 39 | > People who have contributed the most to the project. 40 | 41 | [![](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/images/0)](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/links/0)[![](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/images/1)](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/links/1)[![](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/images/2)](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/links/2)[![](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/images/3)](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/links/3)[![](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/images/4)](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/links/4)[![](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/images/5)](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/links/5)[![](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/images/6)](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/links/6)[![](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/images/7)](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/links/7) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![PYPI](https://img.shields.io/pypi/v/PyGraphT?style=for-the-badge) 2 | ![PyPI - Downloads](https://img.shields.io/pypi/dw/pygraph?style=for-the-badge) 3 | ![GitHub issues](https://img.shields.io/github/issues/richecr/PyGraph?style=for-the-badge) 4 | ![GitHub pull requests](https://img.shields.io/github/issues-pr/richecr/PyGraph?style=for-the-badge) 5 | 6 | # [PyGraph](https://richramalho.github.io/PyGraph/) 7 | [![Build Status](https://travis-ci.org/richecr/PyGraph.svg?branch=master)](https://travis-ci.org/richecr/PyGraph) 8 | > Biblioteca com intuito de implementar os conceitos de Teoria dos Grafos. 9 | 10 | - [PyGraphT - PYPI](https://pypi.org/project/PyGraphT/) 11 | 12 | ## Como usar: 13 | 14 | - Você pode acessar a [documentação da API](https://richramalho.github.io/PyGraph/) e ver o funcionamento e alguns exemplos. 15 | 16 | ## Objetivo: 17 | > O principal objetivo é implementar a maioria dos algoritmos de Teoria dos Grafos. 18 | 19 | - Praticar os conhecimentos obtidos em Teoria dos Grafos. 20 | - Facilitar o uso dos algoritmos de grafos. 21 | 22 | ## Estrutura: 23 | > O modelo UML dos tipos dos grafos que serão implementados: 24 | 25 | - Fique a vontade para editar o modelo UML ou dar sugestões por meio de issues. 26 | 27 | - [Modelo para a comunidade editar](https://www.lucidchart.com/invitations/accept/ac0a364a-2154-4e72-a333-4c9f2cc71629) 28 | 29 | ![Imgur](https://i.imgur.com/LB8yW6f.png) 30 | 31 | ## Como contribuir ? :smiley: 32 | 33 | - PRs são aceitas! 34 | - Se você pensou em uma feature legal ou descobriu algum bug e não tem tempo para codificar, abra uma issue. 35 | - Nós seguimos as diretrizes do [PEP 8](https://www.python.org/dev/peps/pep-0008/). Portanto, antes de fazer uma PR verifique se seu código obedece os padrões do PEP 8(pycodestyle). 36 | - Execute os testes antes de enviar sua PR(pytest). 37 | - Sempre documente seu código. 38 | - Para mais detalhes sobre como contribuir, acesse o [CONTRIBUTING.md](CONTRIBUTING.md). 39 | 40 | Fique tranquilo para enviar sugestões, fazer alterações e/ou procurar erros para nos informar criando uma issue e até mesmo corrigindo e mandando um PR. :relaxed: 41 | 42 | ## Quer contribuir, mas não com código ? 43 | 44 | Não tem problema, temos lugar para todo mundo. Você não precisa codificar pra ajudar, pode contribuir com ideias, encontrando problemas, contribuindo com a documentação e/ou dando sugestões e etc. 45 | 46 | Mas se você quiser codificar e dar seus primeiros passos por aqui seja muito bem vindo(a), todos estamos aqui pra aprender. 47 | 48 | ## Hall of Fame 49 | > Pessoas que mais contribuem com o projeto. 50 | 51 | [![](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/images/0)](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/links/0)[![](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/images/1)](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/links/1)[![](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/images/2)](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/links/2)[![](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/images/3)](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/links/3)[![](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/images/4)](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/links/4)[![](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/images/5)](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/links/5)[![](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/images/6)](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/links/6)[![](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/images/7)](https://sourcerer.io/fame/Rickecr/Rickecr/PyGraph/links/7) 52 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richecr/PyGraph/f0dcd3c253186d18b8b809575e702afa3c87ddef/__init__.py -------------------------------------------------------------------------------- /__tests__/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richecr/PyGraph/f0dcd3c253186d18b8b809575e702afa3c87ddef/__tests__/__init__.py -------------------------------------------------------------------------------- /__tests__/test_graph.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from ..py_graph_t.Graph import Graph 4 | from ..py_graph_t.util.ValueBinding import ValueBinding 5 | from ..py_graph_t.edges.SimpleEdge import SimpleEdge 6 | from ..py_graph_t.vertex.SimpleVertex import SimpleVertex 7 | from ..py_graph_t.exceptions.SimpleGraphException import ( 8 | VertexDuplicatedException, 9 | VertexNotExistsException, 10 | EdgeNotFoundException, 11 | EdgeNameExistsException 12 | ) 13 | 14 | 15 | @pytest.fixture 16 | def simple_graph(): 17 | g = Graph() 18 | g.vertices = dict() 19 | g.edges = [] 20 | g.add_vertex("a") 21 | g.add_vertex("b") 22 | g.add_vertex("c") 23 | g.add_edge("a", "b", name="s") 24 | g.add_edge("b", "c", name="t") 25 | g.add_edge("a", "a", name="d") 26 | return g 27 | 28 | 29 | class TestGraph: 30 | g = Graph() 31 | 32 | def test_add_vertex(self, simple_graph): 33 | simple_graph.add_vertex("e") 34 | assert simple_graph.vertex_exists("e") is True 35 | assert "e" in simple_graph.get_all_vertex().keys() 36 | 37 | def test_exception_add_vertex_duplicate(self, simple_graph): 38 | with pytest.raises(VertexDuplicatedException): 39 | assert simple_graph.add_vertex("a") 40 | 41 | def test_delete_vertex(self, simple_graph): 42 | num_vertex = simple_graph.num_vertex() 43 | simple_graph.add_vertex("e") 44 | v = simple_graph.delete_vertex("e") 45 | assert v.__str__() == "Vértice e" 46 | assert simple_graph.num_vertex() == num_vertex 47 | 48 | def test_exception_delete_vertex_not_exists(self, simple_graph): 49 | with pytest.raises(VertexNotExistsException): 50 | assert simple_graph.delete_vertex("e") 51 | 52 | def test_delete_vertex_terminal(self, simple_graph): 53 | simple_graph.delete_vertex("a") 54 | expected = 1 55 | assert simple_graph.num_edges() == expected 56 | 57 | def test_show_edge(self, simple_graph): 58 | vertex_z = simple_graph.add_vertex("z") 59 | vertex_x = simple_graph.add_vertex("x") 60 | edge_zx = simple_graph.add_edge("z", "x", "zx") 61 | edge_test = SimpleEdge("zx", vertex_z, vertex_x) 62 | assert simple_graph.show_edge("z", "x") == edge_test 63 | 64 | def test_exception_show_edge_vertex_not_exists(self, simple_graph): 65 | vertex_z = simple_graph.add_vertex("z") 66 | with pytest.raises(VertexNotExistsException): 67 | assert simple_graph.show_edge("z", "x") 68 | 69 | def test_exception_show_edge_not_exists(self, simple_graph): 70 | vertex_z = simple_graph.add_vertex("z") 71 | vertex_x = simple_graph.add_vertex("x") 72 | with pytest.raises(EdgeNotFoundException): 73 | assert simple_graph.show_edge("z", "x") 74 | 75 | def test_add_edge(self, simple_graph): 76 | vertex_z = simple_graph.add_vertex("z") 77 | vertex_x = simple_graph.add_vertex("x") 78 | assert simple_graph.add_edge("z", "x", "zx") == \ 79 | SimpleEdge("zx", vertex_z, vertex_x) 80 | 81 | def test_exception_add_edge_vertex_not_exists(self, simple_graph): 82 | vertex_z = simple_graph.add_vertex("z") 83 | vertex_x = SimpleVertex("x") 84 | with pytest.raises(VertexNotExistsException): 85 | assert simple_graph.add_edge("z", "x", "zx") == \ 86 | SimpleEdge("zx", vertex_z, vertex_x) 87 | 88 | def test_exception_add_edge_name_exists(self, simple_graph): 89 | vertex_z = simple_graph.add_vertex("z") 90 | vertex_x = simple_graph.add_vertex("x") 91 | with pytest.raises(EdgeNameExistsException): 92 | assert simple_graph.add_edge("z", "x", "d") == \ 93 | SimpleEdge("zx", vertex_z, vertex_x) 94 | 95 | def test_delete_edge(self, simple_graph): 96 | vertex_z = simple_graph.add_vertex("z") 97 | vertex_x = simple_graph.add_vertex("x") 98 | edge_test = simple_graph.add_edge("z", "x", "zx") 99 | assert simple_graph.delete_edge("z", "x") == edge_test 100 | 101 | def test_delete_edge(self, simple_graph): 102 | vertex_z = simple_graph.add_vertex("z") 103 | vertex_x = simple_graph.add_vertex("x") 104 | edge_test = simple_graph.add_edge("z", "x", "zx") 105 | assert simple_graph.delete_edge("z", "x") == edge_test 106 | 107 | def test_exception_delete_edge_not_exists(self, simple_graph): 108 | vertex_z = simple_graph.add_vertex("z") 109 | vertex_x = simple_graph.add_vertex("x") 110 | with pytest.raises(EdgeNotFoundException): 111 | assert simple_graph.delete_edge("z", "x") 112 | 113 | def test_is_terminal(self, simple_graph): 114 | vertex_z = simple_graph.add_vertex("z") 115 | vertex_x = simple_graph.add_vertex("x") 116 | edge_test = simple_graph.add_edge("z", "x", "zx") 117 | assert simple_graph.is_terminal(edge_test, "z") is True 118 | assert simple_graph.is_terminal(edge_test, "x") is True 119 | assert simple_graph.is_terminal(edge_test, "a") is False 120 | 121 | def test_num_vertex(self, simple_graph): 122 | assert simple_graph.num_vertex() == 3 123 | vertex_z = simple_graph.add_vertex("z") 124 | vertex_x = simple_graph.add_vertex("x") 125 | assert simple_graph.num_vertex() == 5 126 | simple_graph.delete_vertex("z") 127 | simple_graph.delete_vertex("x") 128 | assert simple_graph.num_vertex() == 3 129 | 130 | def test_vertex_exists(self, simple_graph): 131 | vertex_z = simple_graph.add_vertex("z") 132 | assert simple_graph.vertex_exists("a") is True 133 | assert simple_graph.vertex_exists("z") is True 134 | assert simple_graph.vertex_exists("x") is False 135 | 136 | def test_edge_exists(self, simple_graph): 137 | vertex_z = simple_graph.add_vertex("z") 138 | vertex_x = simple_graph.add_vertex("x") 139 | edge_test = simple_graph.add_edge("z", "x", "zx") 140 | assert simple_graph.edge_exists("z", "x") is True 141 | 142 | def test_edge_not_exists(self, simple_graph): 143 | vertex_z = simple_graph.add_vertex("z") 144 | assert simple_graph.edge_exists("z", "a") is False 145 | 146 | def test_num_edges(self, simple_graph): 147 | assert simple_graph.num_edges() == 3 148 | vertex_z = simple_graph.add_vertex("z") 149 | vertex_x = simple_graph.add_vertex("x") 150 | edge_test = simple_graph.add_edge("z", "x", "zx") 151 | assert simple_graph.num_edges() == 4 152 | simple_graph.delete_edge("z", "x") 153 | assert simple_graph.num_edges() == 3 154 | 155 | def test_vertex_neighbors(self, simple_graph): 156 | vertex_a = SimpleVertex("a") 157 | vertex_b = SimpleVertex("b") 158 | expected = [vertex_b, vertex_a] 159 | assert simple_graph.vertex_neighbors("a") == expected 160 | 161 | def test_exception_vertex_neighbors_vertex_not_exists(self, simple_graph): 162 | with pytest.raises(VertexNotExistsException): 163 | assert simple_graph.vertex_neighbors("z") 164 | 165 | def test_vertex_degree(self, simple_graph): 166 | assert simple_graph.vertex_degree("a") == 2 167 | 168 | def test_exception_vertex_degree_vertex_not_exists(self, simple_graph): 169 | with pytest.raises(VertexNotExistsException): 170 | assert simple_graph.vertex_degree("z") 171 | 172 | def test_is_vertices_adjacents(self, simple_graph): 173 | vertex_z = simple_graph.add_vertex("z") 174 | vertex_x = simple_graph.add_vertex("x") 175 | assert simple_graph.is_vertices_adjacents("a", "b") is True 176 | assert simple_graph.is_vertices_adjacents("z", "x") is False 177 | 178 | def test_exception_is_vertices_adjacents_not_exists(self, simple_graph): 179 | vertex_x = simple_graph.add_vertex("x") 180 | with pytest.raises(VertexNotExistsException): 181 | assert simple_graph.is_vertices_adjacents("z", "x") 182 | 183 | def test_get_all_vertex(self, simple_graph): 184 | vertex_a = SimpleVertex("a") 185 | vertex_b = SimpleVertex("b") 186 | vertex_c = SimpleVertex("c") 187 | expected = {"c": vertex_c, "b": vertex_b, "a": vertex_a} 188 | assert simple_graph.get_all_vertex() == expected 189 | 190 | def test_list_graph_vertices(self, simple_graph): 191 | expected = ["a", "b", "c"] 192 | assert simple_graph.list_graph_vertices() == expected 193 | 194 | def test_list_graph_edges(self, simple_graph): 195 | expected = ["s", "t", "d"] 196 | assert simple_graph.list_graph_edges() == expected 197 | 198 | def test_has_cycle(self, simple_graph): 199 | simple_graph.delete_edge("a", "a") 200 | vertex_z = simple_graph.add_vertex("z") 201 | vertex_x = simple_graph.add_vertex("x") 202 | simple_graph.add_edge("z", "x", "zx") 203 | simple_graph.add_edge("z", "a", "za") 204 | simple_graph.add_edge("a", "x", "ax") 205 | assert simple_graph.has_cycle() is True 206 | 207 | def test_has_cycle_simples(self, simple_graph): 208 | assert simple_graph.has_cycle() is True 209 | simple_graph.delete_edge("a", "a") 210 | assert simple_graph.has_cycle() is False 211 | 212 | def test_has_loop(self, simple_graph): 213 | assert simple_graph.has_loop() is True 214 | simple_graph.delete_edge("a", "a") 215 | assert simple_graph.has_cycle() is False 216 | 217 | def test_check_regular_graph(self, simple_graph): 218 | simple_graph.delete_edge("a", "a") 219 | simple_graph.add_edge("c", "a", "ca") 220 | assert simple_graph.check_regular_graph() is True 221 | 222 | def test_incidence_list(self, simple_graph): 223 | vb1 = ValueBinding("a", "s", 1) 224 | vb2 = ValueBinding("a", "t", 0) 225 | vb3 = ValueBinding("a", "d", 2) 226 | 227 | vb4 = ValueBinding("b", "s", 1) 228 | vb5 = ValueBinding("b", "t", 1) 229 | vb6 = ValueBinding("b", "d", 0) 230 | 231 | vb7 = ValueBinding("c", "s", 0) 232 | vb8 = ValueBinding("c", "t", 1) 233 | vb9 = ValueBinding("c", "d", 0) 234 | expected = [vb1, vb2, vb3, vb4, vb5, vb6, vb7, vb8, vb9] 235 | assert simple_graph.incidence_list() == expected 236 | 237 | def test_incidence_list_should_return_a_list(self, simple_graph): 238 | list_ = simple_graph.incidence_list() 239 | expected = True 240 | assert isinstance(list_, list) == expected 241 | 242 | def test_incidence_list_length(self, simple_graph): 243 | vertices_len = len(simple_graph.vertices) 244 | edges_len = len(simple_graph.edges) 245 | expected = vertices_len * edges_len 246 | result = len(simple_graph.incidence_list()) 247 | assert expected == result 248 | 249 | def test_adjacency_matrix_should_return_dict(self, simple_graph): 250 | m = simple_graph.adjacency_matrix() 251 | expected = True 252 | assert isinstance(m, dict) == expected 253 | 254 | def test_adjacency_matrix_get_correct_vertexes(self, simple_graph): 255 | m = simple_graph.adjacency_matrix() 256 | vertexes = m.keys() 257 | assert list(vertexes) == ["a", "b", "c"] 258 | 259 | def test_adjacency_matrix_get_correct_edges(self, simple_graph): 260 | m = simple_graph.adjacency_matrix() 261 | edges = list(m.values()) 262 | edges_a = edges[0] 263 | edges_b = edges[1] 264 | edges_c = edges[2] 265 | 266 | assert edges_a["a"] == int(simple_graph.edge_exists("a", "a"))*2 267 | assert edges_b["b"] == int(simple_graph.edge_exists("b", "b"))*2 268 | assert edges_c["c"] == int(simple_graph.edge_exists("c", "c"))*2 269 | assert edges_a["b"] == edges_b["a"] 270 | assert edges_a["c"] == edges_c["a"] 271 | assert edges_b["c"] == edges_c["b"] 272 | -------------------------------------------------------------------------------- /__tests__/test_simple_graph.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from ..py_graph_t.SimpleGraph import SimpleGraph 4 | from ..py_graph_t.exceptions.SimpleGraphException import ( 5 | EdgeDuplicatedException, 6 | LoopDetectedException 7 | ) 8 | 9 | 10 | class TestSimpleGraph: 11 | graph = SimpleGraph() 12 | neighbors_true = [] 13 | 14 | def setup_method(self): 15 | self.graph = SimpleGraph() 16 | self.neighbors_true = [] 17 | self.graph.add_vertex("a") 18 | self.graph.add_vertex("b") 19 | self.graph.add_edge("a", "b", "ab") 20 | for x in range(10): 21 | self.graph.add_vertex(str(x)) 22 | for x in range(1, 5): 23 | self.neighbors_true.append(self.graph.vertices[str(x)]) 24 | self.graph.add_edge("0", str(x), "x") 25 | 26 | def test_num_vertex(self): 27 | assert self.graph.num_vertex() == 12 28 | 29 | def test_add_vertex(self): 30 | value = "f" 31 | vertex = self.graph.add_vertex(value) 32 | assert str(vertex) == 'Vértice f' 33 | 34 | def test_delete_vertex(self): 35 | vertex_delete = self.graph.delete_vertex("a") 36 | assert self.graph.num_vertex() == 11 37 | assert str(vertex_delete) == "Vértice a" 38 | 39 | 40 | def test_is_terminal(self): 41 | self.graph.add_vertex("j") 42 | self.graph.add_vertex("k") 43 | edge = self.graph.add_edge("j", "k", "jk") 44 | assert self.graph.is_terminal(edge, 'j') and \ 45 | self.graph.is_terminal(edge, 'k') 46 | 47 | def test_vertex_exists(self): 48 | assert self.graph.vertex_exists("a") 49 | 50 | def test_edge_exists(self): 51 | assert self.graph.edge_exists("a", "b") 52 | 53 | def test_num_edges(self): 54 | assert self.graph.num_edges() == 5 55 | 56 | def test_vertex_neighbors(self): 57 | assert self.graph.vertex_neighbors("0") == self.neighbors_true 58 | 59 | def test_vertex_degree(self): 60 | assert len(self.graph.vertex_neighbors("b")) == 1 61 | 62 | def test_vertices_adjacency(self): 63 | neighbors_vertices = self.graph.vertex_neighbors("a") 64 | vertex_b = self.graph.vertices.get("b") 65 | assert vertex_b in neighbors_vertices 66 | 67 | def test_get_all_vertex(self): 68 | assert str(self.graph.get_all_vertex()) == "{'a': Vértice a, " + \ 69 | "'b': Vértice b, '0': Vértice 0, '1': Vértice 1, " + \ 70 | "'2': Vértice 2, '3': Vértice 3, '4': Vértice 4, " + \ 71 | "'5': Vértice 5, '6': Vértice 6, '7': Vértice 7, " + \ 72 | "'8': Vértice 8, '9': Vértice 9}" 73 | 74 | def test_list_graph_vertices(self): 75 | vertices = [] 76 | for vertex in self.graph.vertices: 77 | vertices.append(vertex) 78 | assert str(self.graph.list_graph_vertices()) == \ 79 | "['a', 'b', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']" 80 | 81 | def test_list_graph_edges(self): 82 | edges = [] 83 | for edge in self.graph.edges: 84 | edges.append(edge.name) 85 | assert str(self.graph.list_graph_edges()) == \ 86 | "['ab', 'x', 'x', 'x', 'x']" 87 | 88 | def test_show_edge(self): 89 | assert str(self.graph.show_edge('a', 'b')) == \ 90 | str('ab: Vértice a -> Vértice b') 91 | 92 | def test_true_cycle_graph(self): 93 | self.graph.add_vertex("c") 94 | self.graph.add_edge("b", "c", 2) 95 | self.graph.add_edge("c", "a", 3) 96 | assert self.graph.has_cycle() is True 97 | assert self.graph.has_loop() is False 98 | 99 | def test_false_cycle_graph(self): 100 | self.graph.add_vertex("c") 101 | self.graph.add_edge("b", "c", 2) 102 | self.graph.add_edge("c", "a", 3) 103 | self.graph.delete_edge("c", "a") 104 | self.graph.add_vertex("d") 105 | self.graph.add_edge("c", "d", 3) 106 | assert self.graph.has_cycle() is False 107 | assert self.graph.has_loop() is False 108 | 109 | def test_loop(self): 110 | with pytest.raises(LoopDetectedException): 111 | assert self.graph.add_edge("d", "d") 112 | assert self.graph.has_loop() is False 113 | 114 | def test_true_regular_graph(self): 115 | self.graph.add_vertex("c") 116 | self.graph.add_edge("b", "c", 2) 117 | self.graph.add_edge("c", "a", 3) 118 | self.graph.delete_edge("c", "a") 119 | self.graph.add_vertex("d") 120 | self.graph.add_edge("c", "d", 3) 121 | self.graph.delete_vertex("d") 122 | for i in range(0, 10): 123 | self.graph.delete_vertex(str(i)) 124 | 125 | self.graph.add_vertex("d") 126 | self.graph.delete_edge("b", "c") 127 | self.graph.add_edge("c", "d", 3) 128 | print(self.graph.__str__()) 129 | assert self.graph.check_regular_graph() is True 130 | 131 | def test_false_regular_graph(self): 132 | self.graph.add_vertex("c") 133 | self.graph.add_edge("b", "c", 2) 134 | self.graph.add_edge("c", "a", 3) 135 | self.graph.delete_edge("c", "a") 136 | self.graph.add_vertex("d") 137 | self.graph.add_edge("c", "d", 3) 138 | self.graph.delete_vertex("d") 139 | for i in range(0, 10): 140 | self.graph.delete_vertex(str(i)) 141 | 142 | self.graph.add_vertex("d") 143 | self.graph.delete_edge("b", "c") 144 | self.graph.add_edge("c", "d", 3) 145 | self.graph.add_edge("b", "c", 3) 146 | assert self.graph.check_regular_graph() is False 147 | 148 | def test_duplicated_edge(self): 149 | with pytest.raises(EdgeDuplicatedException): 150 | assert self.graph.add_edge("a", "b") 151 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /docs/edges/simple_edge.md: -------------------------------------------------------------------------------- 1 | # Aresta Simples -------------------------------------------------------------------------------- /docs/edges/weighted_edge.md: -------------------------------------------------------------------------------- 1 | # Aresta Ponderada -------------------------------------------------------------------------------- /docs/graphs/complete_graph.md: -------------------------------------------------------------------------------- 1 | # [Grafo Completo](https://github.com/Rickecr/PyGraph/blob/efc5d75006ac82773a4e7102c9d86d9e06ef31f2/py_graph_t/CompleteGraph.py#L4) 2 | 3 | Esse é a representação do Grafo Completo. Herda características e métodos do [Graph](graph.md#grafo-base), entretanto sobrescreve alguns métodos para que possa ser feito suas restrições específicas. 4 | 5 | Restrições que esse tipo de grafo possue: 6 | 7 | - Todos os vértices devem ser adjacentes a todos os outros vértices. 8 | 9 | Nessa implementação as arestas _não tem pesos_. 10 | 11 | ## Importar: 12 | 13 | ```python 14 | from py_graph_t import CompleteGraph 15 | ``` 16 | 17 | ## Métodos: 18 | 19 | Possui todos os métodos do [Graph](graph.md#grafo-base), mas como tem restrições específicas foi necessário sobrescrever alguns métodos. 20 | 21 | ### Métodos sobrescritos: 22 | 23 | EM CONSTRUÇÃO!!! 24 | -------------------------------------------------------------------------------- /docs/graphs/graph.md: -------------------------------------------------------------------------------- 1 | # [Grafo Base](https://github.com/Rickecr/PyGraph/blob/deb3fa4cb011f42255dd48ee4c54660205928af2/py_graph_t/Graph.py#L12) 2 | 3 | Esse é o grafo que todos os outros grafos vão herdar suas características/métodos. 4 | 5 | Esse grafo não possui nenhum tipo de restrição. Pois todos os outros grafos irão sobrescrever os métodos necessários para aplicar suas restrições. 6 | 7 | ## Importar: 8 | 9 | ```python 10 | from py_graph_t import Graph 11 | ``` 12 | 13 | ## Métodos: 14 | 15 | | Método | Parâmetros | O que faz ? | Retorno | 16 | | ---------------------------------------------------------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------ | ----------------------- | 17 | | [add_vertex](#adicionar-um-vértice) | value | Método que adiciona um vértice ao grafo. | SimpleVertex adicionado | 18 | | [delete_vertex](#deletar-um-vértice) | value | Método que remove um vertice do grafo e consequentemente todas as arestas conectadas ao vertice. | SimpleVertex removido | 19 | | [add_edge](#adicionar-uma-aresta) | value_a, value_b, name(opcional) | Método que adiciona uma aresta ao grafo. | SimpleEdge adicionado. | 20 | | [delete_edge](#deletar-uma-aresta) | value_a, value_b | Método que remove uma aresta do grafo. | SimpleEdge removido. | 21 | | [show_edge](#visualizar-aresta) | value_a, value_b | Método que retorna uma aresta entre dois vértices, se ela existe. | SimpleEdge. | 22 | | [is_terminal](#verificar-se-um-vértice-é-terminal-de-uma-aresta) | edge, value | Método que verifica se um dado vértice é terminal de uma dada aresta. | Boolean | 23 | | [num_vertex](#número-de-vértices) | --- | Método que retorna o número de vértices no grafo. | Integer | 24 | | [num_edges](#número-de-arestas) | --- | Método que retorna o número de arestas no grafo. | Integer | 25 | | [vertex_exists](#verifica-se-um-vértice-existe) | value | Método que indica se um determinado vértice pertence ao Grafo. | Boolean | 26 | | [edge_exists](#verifica-se-uma-aresta-existe) | value_a, value_b | Método que indica se uma determinada aresta pertence ao Grafo. | Boolean | 27 | | [vertex_neighbors](#vizinhos-de-um-vértice) | value | Método que encontra vertices vizinhos do vertice de entrada. | List | 28 | | [vertex_degree](#grau-do-vértice) | value | Método que retorna o grau do vértice de entrada. | Integer | 29 | | [is_vertices_adjacents](#verifica-se-os-vértices-são-adjacentes) | value_a, value_b | Método que indica se os vértices de entrada são adjacentes. | Boolean | 30 | | [get_all_vertex](#lista-dos-vértices-do-grafo) | --- | Método que retorna uma lista com os vértices do grafo. | List | 31 | | [list_graph_vertices](#lista-com-todos-os-identificadores-dos-vértices) | --- | Método que retorna lista com todos os identificadores dos vértices do grafo. | List | 32 | | [list_graph_edges](#lista-com-os-nomes-das-arestas) | --- | Método que retorna lista com todos os nomes as arestas do grafo. | List | 33 | | [cycle](#) | v, visited, parent | Método que verifica se tem ciclo no subgrafo a partir do vértice v. | Boolean | 34 | | [has_cycle](#verifica-se-um-grafo-possui-ciclos-loops-também-são-detectados) | --- | Método que verifica se o grafo possui um ciclo. Loops também são detectados. | Boolean | 35 | | [has_loop](#verifica-se-um-grafo-possui-um-loop) | --- | Método que verifica se o grafo possui um loop. | Boolean | 36 | | [check_regular_graph](#verifica-a-regularidade-de-um-grafo) | --- | Método que verifica a regularidade de um grafo. | Boolean | 37 | | [incidence_list](#incidência-de-um-grafo) | --- | Método que retorna uma lista de objetos que contem a incidencia dos vertices com as arestas. | List | 38 | | [adjacency_matrix](#adjacência-de-um-grafo) | --- | Método que retorna a representação em forma de matriz de adjacência do grafo. | Dict | 39 | | [`__str__`](#representação-textual) | --- | Método que retorna a representação textual do grafo. | String | 40 | 41 | ## Exemplos de uso: 42 | 43 | Não faz muito sentido ter um grafo como esse, ele existe na biblioteca apenas para servir para reuso. 44 | 45 | ### Adicionar um vértice 46 | 47 | ```python 48 | grafo = Graph() 49 | grafo.add_vertex("a") 50 | grafo.add_vertex("b") 51 | grafo.add_vertex("c") 52 | ``` 53 | 54 | ### Deletar um vértice 55 | 56 | ```python 57 | grafo = Graph() 58 | grafo.delete_vertex("a") 59 | grafo.delete_vertex("b") 60 | grafo.delete_vertex("c") 61 | ``` 62 | 63 | ### Adicionar uma aresta 64 | 65 | ```python 66 | grafo = Graph() 67 | grafo.add_vertex("a") 68 | grafo.add_vertex("b") 69 | grafo.add_edge("a", "b", name="Aresta AB") 70 | grafo.add_edge("b", "a", name="Aresta BA") 71 | grafo.add_edge("a", "a", name="Aresta AA") 72 | ``` 73 | 74 | ### Deletar uma aresta 75 | 76 | ```python 77 | grafo = Graph() 78 | grafo.add_vertex("a") 79 | grafo.add_vertex("b") 80 | grafo.add_edge("a", "b", name="Aresta AB") 81 | grafo.add_edge("b", "a", name="Aresta BA") 82 | grafo.add_edge("a", "a", name="Aresta AA") 83 | grafo.delete_edge("a", "a") 84 | ``` 85 | 86 | ### Visualizar aresta 87 | 88 | ```python 89 | grafo = Graph() 90 | grafo.add_vertex("a") 91 | grafo.add_vertex("b") 92 | grafo.add_edge("a", "b", name="Aresta AB") 93 | grafo.add_edge("b", "a", name="Aresta BA") 94 | grafo.add_edge("a", "a", name="Aresta AA") 95 | print(grafo.show_edge("a", "b")) 96 | ``` 97 | 98 | ### Verificar se um vértice é terminal de uma aresta 99 | 100 | ```python 101 | grafo = Graph() 102 | grafo.add_vertex("a") 103 | grafo.add_vertex("b") 104 | grafo.add_edge("a", "b", name="Aresta AB") 105 | grafo.add_edge("b", "a", name="Aresta BA") 106 | grafo.add_edge("a", "a", name="Aresta AA") 107 | edge = grafo.show_edge("a", "b") 108 | grafo.is_terminal(edge, "b") 109 | grafo.is_terminal(edge, "a") 110 | ``` 111 | 112 | ### Número de vértices 113 | 114 | ```python 115 | grafo = Graph() 116 | grafo.add_vertex("a") 117 | grafo.add_vertex("b") 118 | print(grafo.num_vertex()) 119 | ``` 120 | 121 | ### Número de arestas 122 | 123 | ```python 124 | grafo = Graph() 125 | grafo.add_vertex("a") 126 | grafo.add_vertex("b") 127 | grafo.add_edge("a", "b", name="Aresta AB") 128 | grafo.add_edge("b", "a", name="Aresta BA") 129 | print(grafo.num_edges()) 130 | ``` 131 | 132 | ### Verifica se um vértice existe 133 | 134 | ```python 135 | grafo = Graph() 136 | grafo.add_vertex("a") 137 | grafo.add_vertex("b") 138 | print(grafo.vertex_exists("a")) 139 | ``` 140 | 141 | ### Verifica se uma aresta existe 142 | 143 | ```python 144 | grafo = Graph() 145 | grafo.add_vertex("a") 146 | grafo.add_vertex("b") 147 | grafo.add_edge("a", "b", name="Aresta AB") 148 | print(grafo.edge_exists("a", "b")) 149 | ``` 150 | 151 | ### Vizinhos de um vértice 152 | 153 | ```python 154 | grafo = Graph() 155 | grafo.add_vertex("a") 156 | grafo.add_vertex("b") 157 | grafo.add_edge("a", "b", name="Aresta AB") 158 | grafo.add_edge("b", "a", name="Aresta BA") 159 | print(grafo.vertex_neighbors("a")) 160 | ``` 161 | 162 | ### Grau do vértice 163 | 164 | ```python 165 | grafo = Graph() 166 | grafo.add_vertex("a") 167 | grafo.add_vertex("b") 168 | grafo.add_edge("a", "b", name="Aresta AB") 169 | grafo.add_edge("b", "a", name="Aresta BA") 170 | print(grafo.vertex_degree("a")) 171 | ``` 172 | 173 | ### Verifica se os vértices são adjacentes 174 | 175 | ```python 176 | grafo = Graph() 177 | grafo.add_vertex("a") 178 | grafo.add_vertex("b") 179 | grafo.add_edge("a", "b", name="Aresta AB") 180 | grafo.add_edge("b", "a", name="Aresta BA") 181 | print(grafo.is_vertices_adjacents("a", "b")) 182 | ``` 183 | 184 | ### Lista dos vértices do grafo 185 | 186 | ```python 187 | grafo = Graph() 188 | grafo.add_vertex("a") 189 | grafo.add_vertex("b") 190 | print(grafo.get_all_vertex()) 191 | ``` 192 | 193 | ### Lista com todos os identificadores dos vértices 194 | 195 | ```python 196 | grafo = Graph() 197 | grafo.add_vertex("a") 198 | grafo.add_vertex("b") 199 | print(grafo.list_graph_vertices()) 200 | ``` 201 | 202 | ### Lista com os nomes das arestas 203 | 204 | ```python 205 | grafo = Graph() 206 | grafo.add_vertex("a") 207 | grafo.add_vertex("b") 208 | print(grafo.get_all_vertex()) 209 | grafo.add_edge("a", "b", name="Aresta AB") 210 | grafo.add_edge("b", "a", name="Aresta BA") 211 | print(grafo.list_graph_edges()) 212 | ``` 213 | 214 | ### Verifica se um grafo possui ciclos, loops também são detectados 215 | 216 | ```python 217 | grafo = Graph() 218 | grafo.add_vertex("a") 219 | grafo.add_vertex("b") 220 | grafo.add_edge("a", "b", name="Aresta AB") 221 | grafo.add_edge("b", "a", name="Aresta BA") 222 | print(grafo.has_cycle()) 223 | ``` 224 | 225 | ### Verifica se um grafo possui um loop 226 | 227 | ```python 228 | grafo = Graph() 229 | grafo.add_vertex("a") 230 | grafo.add_vertex("b") 231 | grafo.add_edge("a", "b", name="Aresta AB") 232 | grafo.add_edge("b", "a", name="Aresta BA") 233 | print(grafo.has_loop()) 234 | ``` 235 | 236 | ### Verifica a regularidade de um grafo 237 | 238 | ```python 239 | grafo = Graph() 240 | grafo.add_vertex("a") 241 | grafo.add_vertex("b") 242 | grafo.add_edge("a", "b", name="Aresta AB") 243 | grafo.add_edge("b", "a", name="Aresta BA") 244 | print(grafo.check_regular_graph()) 245 | ``` 246 | 247 | ### Incidência de um grafo 248 | 249 | ```python 250 | grafo = Graph() 251 | grafo.add_vertex("a") 252 | grafo.add_vertex("b") 253 | grafo.add_edge("a", "b", name="Aresta AB") 254 | grafo.add_edge("b", "a", name="Aresta BA") 255 | print(grafo.incidence_list()) 256 | ``` 257 | 258 | ### Adjacência de um grafo 259 | 260 | ```python 261 | grafo = Graph() 262 | grafo.add_vertex("a") 263 | grafo.add_vertex("b") 264 | grafo.add_edge("a", "b", name="Aresta AB") 265 | grafo.add_edge("b", "a", name="Aresta BA") 266 | print(grafo.adjacency_matrix()) 267 | ``` 268 | 269 | ### Representação textual 270 | 271 | ```python 272 | grafo = Graph() 273 | grafo.add_vertex("a") 274 | grafo.add_vertex("b") 275 | grafo.add_edge("a", "b", name="Aresta AB") 276 | grafo.add_edge("b", "a", name="Aresta BA") 277 | print(grafo.__str__()) 278 | ``` 279 | -------------------------------------------------------------------------------- /docs/graphs/simple_graph.md: -------------------------------------------------------------------------------- 1 | # [Grafo Simples](https://github.com/Rickecr/PyGraph/blob/efc5d75006ac82773a4e7102c9d86d9e06ef31f2/py_graph_t/SimpleGraph.py#L11) 2 | 3 | Esse é a representação do Grafo Simples. Herda características e métodos do [Graph](#graph.md), entretanto sobrescreve alguns métodos para que possa ser feito suas restrições específicas. 4 | 5 | Restrições que esse tipo de grafo possui: 6 | 7 | - Não contêm loops. 8 | - Não contêm arestas paralelas. 9 | 10 | Nessa implementação as arestas _não tem pesos_. 11 | 12 | ## Importar: 13 | 14 | ```python 15 | from py_graph_t import SimpleGraph 16 | ``` 17 | 18 | ## Métodos: 19 | 20 | Possui todos os métodos do [Graph](#graph.md), mas como tem restrições específicas foi necessário sobrescrever alguns métodos. 21 | 22 | ### Métodos sobrescritos: 23 | 24 | | Método | Parâmetros | O que faz ? | Retorno | 25 | | --------------------------------- | -------------------------------- | ---------------------------------------- | ---------------------- | 26 | | [add_edge](#adicionar-uma-aresta) | value_a, value_b, name(opcional) | Método que adiciona uma aresta ao grafo. | SimpleEdge adicionado. | 27 | 28 | ## Exemplos de uso: 29 | 30 | ### Adicionar uma aresta 31 | 32 | ```python 33 | grafo = SimpleGraph() 34 | grafo.add_vertex("a") 35 | grafo.add_vertex("b") 36 | grafo.add_edge("a", "b", name="Aresta AB") 37 | grafo.add_edge("b", "a", name="Aresta BA") 38 | grafo.add_edge("a", "a", name="Aresta AA") # Deve ser lançado um erro(loop) 39 | ``` 40 | 41 | ```python 42 | grafo = SimpleGraph() 43 | grafo.add_vertex("a") 44 | grafo.add_vertex("b") 45 | grafo.add_edge("a", "b", name="Aresta AB") 46 | grafo.add_edge("b", "a", name="Aresta BA") # Deve lançar exceção(ciclo) 47 | ``` 48 | -------------------------------------------------------------------------------- /docs/graphs/weighted_graph.md: -------------------------------------------------------------------------------- 1 | # Grafo Ponderado -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Informações 2 | 3 | - [Documentação](start.md) da biblioteca. 4 | - [PyGraphT - PYPI](https://pypi.org/project/PyGraphT/) 5 | 6 | ## Qual objetivo da biblioteca ? 7 | 8 | O objetivo é a criação de uma biblioteca que facilite o uso de conceitos de Teoria dos Grafos. 9 | 10 | Já que não possuem muitas bibliotecas desse ramo escritas em Python. O objetivo da biblioteca é permitir a fácil utilização dos algoritmos de Grafos. 11 | 12 | Também tem objetivo de fazer com que estudantes contribuam e apliquem seus conhecimentos de Teoria dos Grafos. 13 | 14 | ## Quem somos ? 15 | 16 | Somos alunos da UFCG. 17 | 18 | - [Rich Elton](https://github.com/Rickecr) 19 | - [Matheus Santana](https://github.com/mathsantana) 20 | - [José Davi](https://github.com/JoseDavi) 21 | - [Eduardo Pereira](https://github.com/Eduardoccufcg) 22 | - [Yuri Souza](https://github.com/yuri-s-s) 23 | -------------------------------------------------------------------------------- /docs/start.md: -------------------------------------------------------------------------------- 1 | # Sumário: 2 | 3 | - [Instalar](#instalacao) 4 | - [Grafos](#grafos) 5 | - [Arestas](#arestas) 6 | - [Vértices](#vértices) 7 | 8 | ## Instalar: 9 | 10 | ```bash 11 | $ pip install PyGraphT 12 | ``` 13 | 14 | ## Grafos: 15 | 16 | Os grafos implementados na biblioteca. 17 | 18 | - [Graph](graphs/graph.md) - Grafo base. 19 | - [SimpleGraph](graphs/simple_graph.md) - Grafo Simples. 20 | - [CompleteGraph](graphs/complete_graph.md) - Grafo Completo. 21 | - [WeightedGraph](graphs/weighted_graph.md) - Grafo Ponderado. 22 | 23 | ## Arestas: 24 | 25 | As arestas implementadas na biblioteca para serem usadas pelos grafos. 26 | 27 | - [SimpleEdge](edges/simple_edge.md) - Aresta Simples 28 | - [WeightedEdge](edges/weighted_edge.md) - Aresta Ponderada 29 | 30 | ## Vértices: 31 | 32 | Os vértices implementados na bibliotecas para serem utilizados pelas arestas e grafos. 33 | 34 | - [SimpleVertex](vertices/simple_vertex.md) - Vértice Simples 35 | -------------------------------------------------------------------------------- /docs/vertices/simple_vertex.md: -------------------------------------------------------------------------------- 1 | # Vértice Simples -------------------------------------------------------------------------------- /poetry.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | category = "dev" 3 | description = "Atomic file writes." 4 | marker = "sys_platform == \"win32\"" 5 | name = "atomicwrites" 6 | optional = false 7 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 8 | version = "1.4.0" 9 | 10 | [[package]] 11 | category = "dev" 12 | description = "Classes Without Boilerplate" 13 | name = "attrs" 14 | optional = false 15 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 16 | version = "19.3.0" 17 | 18 | [package.extras] 19 | azure-pipelines = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "pytest-azurepipelines"] 20 | dev = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "pre-commit"] 21 | docs = ["sphinx", "zope.interface"] 22 | tests = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] 23 | 24 | [[package]] 25 | category = "dev" 26 | description = "Cross-platform colored terminal text." 27 | name = "colorama" 28 | optional = false 29 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 30 | version = "0.4.3" 31 | 32 | [[package]] 33 | category = "dev" 34 | description = "Pythonic argument parser, that will make you smile" 35 | name = "docopt" 36 | optional = false 37 | python-versions = "*" 38 | version = "0.6.2" 39 | 40 | [[package]] 41 | category = "dev" 42 | description = "the modular source code checker: pep8 pyflakes and co" 43 | name = "flake8" 44 | optional = false 45 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" 46 | version = "3.8.3" 47 | 48 | [package.dependencies] 49 | mccabe = ">=0.6.0,<0.7.0" 50 | pycodestyle = ">=2.6.0a1,<2.7.0" 51 | pyflakes = ">=2.2.0,<2.3.0" 52 | 53 | [[package]] 54 | category = "dev" 55 | description = "iniconfig: brain-dead simple config-ini parsing" 56 | name = "iniconfig" 57 | optional = false 58 | python-versions = "*" 59 | version = "1.0.1" 60 | 61 | [[package]] 62 | category = "dev" 63 | description = "McCabe checker, plugin for flake8" 64 | name = "mccabe" 65 | optional = false 66 | python-versions = "*" 67 | version = "0.6.1" 68 | 69 | [[package]] 70 | category = "dev" 71 | description = "More routines for operating on iterables, beyond itertools" 72 | name = "more-itertools" 73 | optional = false 74 | python-versions = ">=3.5" 75 | version = "8.4.0" 76 | 77 | [[package]] 78 | category = "dev" 79 | description = "Core utilities for Python packages" 80 | name = "packaging" 81 | optional = false 82 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 83 | version = "20.4" 84 | 85 | [package.dependencies] 86 | pyparsing = ">=2.0.2" 87 | six = "*" 88 | 89 | [[package]] 90 | category = "dev" 91 | description = "File system general utilities" 92 | name = "pathtools" 93 | optional = false 94 | python-versions = "*" 95 | version = "0.1.2" 96 | 97 | [[package]] 98 | category = "dev" 99 | description = "plugin and hook calling mechanisms for python" 100 | name = "pluggy" 101 | optional = false 102 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 103 | version = "0.13.1" 104 | 105 | [package.extras] 106 | dev = ["pre-commit", "tox"] 107 | 108 | [[package]] 109 | category = "dev" 110 | description = "library with cross-python path, ini-parsing, io, code, log facilities" 111 | name = "py" 112 | optional = false 113 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 114 | version = "1.9.0" 115 | 116 | [[package]] 117 | category = "dev" 118 | description = "Python style guide checker" 119 | name = "pycodestyle" 120 | optional = false 121 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 122 | version = "2.6.0" 123 | 124 | [[package]] 125 | category = "dev" 126 | description = "passive checker of Python programs" 127 | name = "pyflakes" 128 | optional = false 129 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 130 | version = "2.2.0" 131 | 132 | [[package]] 133 | category = "dev" 134 | description = "Python parsing module" 135 | name = "pyparsing" 136 | optional = false 137 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" 138 | version = "2.4.7" 139 | 140 | [[package]] 141 | category = "dev" 142 | description = "pytest: simple powerful testing with Python" 143 | name = "pytest" 144 | optional = false 145 | python-versions = ">=3.5" 146 | version = "6.0.1" 147 | 148 | [package.dependencies] 149 | atomicwrites = ">=1.0" 150 | attrs = ">=17.4.0" 151 | colorama = "*" 152 | iniconfig = "*" 153 | more-itertools = ">=4.0.0" 154 | packaging = "*" 155 | pluggy = ">=0.12,<1.0" 156 | py = ">=1.8.2" 157 | toml = "*" 158 | 159 | [package.extras] 160 | checkqa_mypy = ["mypy (0.780)"] 161 | testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] 162 | 163 | [[package]] 164 | category = "dev" 165 | description = "Local continuous test runner with pytest and watchdog." 166 | name = "pytest-watch" 167 | optional = false 168 | python-versions = "*" 169 | version = "4.2.0" 170 | 171 | [package.dependencies] 172 | colorama = ">=0.3.3" 173 | docopt = ">=0.4.0" 174 | pytest = ">=2.6.4" 175 | watchdog = ">=0.6.0" 176 | 177 | [[package]] 178 | category = "dev" 179 | description = "Python 2 and 3 compatibility utilities" 180 | name = "six" 181 | optional = false 182 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" 183 | version = "1.15.0" 184 | 185 | [[package]] 186 | category = "dev" 187 | description = "Python Library for Tom's Obvious, Minimal Language" 188 | name = "toml" 189 | optional = false 190 | python-versions = "*" 191 | version = "0.10.1" 192 | 193 | [[package]] 194 | category = "dev" 195 | description = "Filesystem events monitoring" 196 | name = "watchdog" 197 | optional = false 198 | python-versions = "*" 199 | version = "0.10.3" 200 | 201 | [package.dependencies] 202 | pathtools = ">=0.1.1" 203 | 204 | [package.extras] 205 | watchmedo = ["PyYAML (>=3.10)", "argh (>=0.24.1)"] 206 | 207 | [metadata] 208 | content-hash = "eefb9ecb155b04b75e004492f1b7f42c3a0f5f419afa5fe41a7b5c8d2272fb83" 209 | lock-version = "1.0" 210 | python-versions = "^3.8" 211 | 212 | [metadata.files] 213 | atomicwrites = [ 214 | {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, 215 | {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, 216 | ] 217 | attrs = [ 218 | {file = "attrs-19.3.0-py2.py3-none-any.whl", hash = "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c"}, 219 | {file = "attrs-19.3.0.tar.gz", hash = "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"}, 220 | ] 221 | colorama = [ 222 | {file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"}, 223 | {file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"}, 224 | ] 225 | docopt = [ 226 | {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, 227 | ] 228 | flake8 = [ 229 | {file = "flake8-3.8.3-py2.py3-none-any.whl", hash = "sha256:15e351d19611c887e482fb960eae4d44845013cc142d42896e9862f775d8cf5c"}, 230 | {file = "flake8-3.8.3.tar.gz", hash = "sha256:f04b9fcbac03b0a3e58c0ab3a0ecc462e023a9faf046d57794184028123aa208"}, 231 | ] 232 | iniconfig = [ 233 | {file = "iniconfig-1.0.1-py3-none-any.whl", hash = "sha256:80cf40c597eb564e86346103f609d74efce0f6b4d4f30ec8ce9e2c26411ba437"}, 234 | {file = "iniconfig-1.0.1.tar.gz", hash = "sha256:e5f92f89355a67de0595932a6c6c02ab4afddc6fcdc0bfc5becd0d60884d3f69"}, 235 | ] 236 | mccabe = [ 237 | {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, 238 | {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, 239 | ] 240 | more-itertools = [ 241 | {file = "more-itertools-8.4.0.tar.gz", hash = "sha256:68c70cc7167bdf5c7c9d8f6954a7837089c6a36bf565383919bb595efb8a17e5"}, 242 | {file = "more_itertools-8.4.0-py3-none-any.whl", hash = "sha256:b78134b2063dd214000685165d81c154522c3ee0a1c0d4d113c80361c234c5a2"}, 243 | ] 244 | packaging = [ 245 | {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, 246 | {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, 247 | ] 248 | pathtools = [ 249 | {file = "pathtools-0.1.2.tar.gz", hash = "sha256:7c35c5421a39bb82e58018febd90e3b6e5db34c5443aaaf742b3f33d4655f1c0"}, 250 | ] 251 | pluggy = [ 252 | {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, 253 | {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, 254 | ] 255 | py = [ 256 | {file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"}, 257 | {file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"}, 258 | ] 259 | pycodestyle = [ 260 | {file = "pycodestyle-2.6.0-py2.py3-none-any.whl", hash = "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367"}, 261 | {file = "pycodestyle-2.6.0.tar.gz", hash = "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"}, 262 | ] 263 | pyflakes = [ 264 | {file = "pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"}, 265 | {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, 266 | ] 267 | pyparsing = [ 268 | {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, 269 | {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, 270 | ] 271 | pytest = [ 272 | {file = "pytest-6.0.1-py3-none-any.whl", hash = "sha256:8b6007800c53fdacd5a5c192203f4e531eb2a1540ad9c752e052ec0f7143dbad"}, 273 | {file = "pytest-6.0.1.tar.gz", hash = "sha256:85228d75db9f45e06e57ef9bf4429267f81ac7c0d742cc9ed63d09886a9fe6f4"}, 274 | ] 275 | pytest-watch = [ 276 | {file = "pytest-watch-4.2.0.tar.gz", hash = "sha256:06136f03d5b361718b8d0d234042f7b2f203910d8568f63df2f866b547b3d4b9"}, 277 | ] 278 | six = [ 279 | {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, 280 | {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, 281 | ] 282 | toml = [ 283 | {file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"}, 284 | {file = "toml-0.10.1.tar.gz", hash = "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f"}, 285 | ] 286 | watchdog = [ 287 | {file = "watchdog-0.10.3.tar.gz", hash = "sha256:4214e1379d128b0588021880ccaf40317ee156d4603ac388b9adcf29165e0c04"}, 288 | ] 289 | -------------------------------------------------------------------------------- /py_graph_t/CompleteGraph.py: -------------------------------------------------------------------------------- 1 | from .Graph import Graph 2 | 3 | 4 | class CompleteGraph(Graph): 5 | """ 6 | Implementação de um Grafo Completo. 7 | 8 | Em um grafo completo ``todos os vértices`` são: 9 | - Adjacentes a todos os outros vértices 10 | 11 | Nessa implementação as ``arestas não tem pesos``. 12 | """ 13 | def __init__(self): 14 | super().__init__() 15 | pass 16 | -------------------------------------------------------------------------------- /py_graph_t/Graph.py: -------------------------------------------------------------------------------- 1 | from .vertex.SimpleVertex import SimpleVertex 2 | from .edges.SimpleEdge import SimpleEdge 3 | from .util.ValueBinding import ValueBinding 4 | 5 | from .exceptions.SimpleGraphException import ( 6 | VertexNotExistsException, 7 | EdgeNotFoundException, 8 | VertexDuplicatedException, 9 | EdgeNameExistsException 10 | ) 11 | 12 | 13 | class Graph: 14 | """Implementação de um grafo base.""" 15 | 16 | def __init__(self): 17 | self.vertices = dict() 18 | self.edges = [] 19 | pass 20 | 21 | def add_vertex(self, value): 22 | """ 23 | Método que adiciona um vértice ao grafo. 24 | 25 | Parâmetros: 26 | ---------- 27 | value: 28 | - Valor a ser colocado no vértice. 29 | - Identificador do vértice. 30 | """ 31 | if not self.vertices.__contains__(value): 32 | self.vertices[value] = SimpleVertex(value) 33 | return self.vertices[value] 34 | else: 35 | raise VertexDuplicatedException() 36 | 37 | def delete_vertex(self, value): 38 | """ 39 | Método que remove um vertice do grafo e consequentemente todas 40 | as arestas 41 | conectadas ao vertice. 42 | 43 | Parâmetros: 44 | ---------- 45 | value: 46 | - Identificador do vértice a ser removido 47 | """ 48 | if self.vertex_exists(value): 49 | vertex_removed = self.vertices[value] 50 | for i in range(len(self.edges)-1, -1, -1): 51 | edge = self.edges[i] 52 | if self.is_terminal(edge, value): 53 | self.edges.pop(i) 54 | 55 | self.vertices.__delitem__(value) 56 | return vertex_removed 57 | else: 58 | raise VertexNotExistsException() 59 | 60 | def show_edge(self, value_a, value_b): 61 | """ 62 | Método que retorna uma aresta entre dois vértices, se ela 63 | existe. 64 | 65 | Parâmetros: 66 | ---------- 67 | value_a: 68 | - Identificador do vértice. 69 | value_b: 70 | - Identificador do vértice. 71 | """ 72 | vertex_a = self.vertices.get(value_a) 73 | vertex_b = self.vertices.get(value_b) 74 | 75 | if vertex_a is None or vertex_b is None: 76 | raise VertexNotExistsException 77 | 78 | edge_test = SimpleEdge(vertex_a=vertex_a, vertex_b=vertex_b) 79 | 80 | edge_out = None 81 | for edge in self.edges: 82 | if edge_test.__eq__(edge): 83 | edge_out = edge 84 | 85 | if edge_out is None: 86 | raise EdgeNotFoundException() 87 | 88 | return edge_out 89 | 90 | def add_edge(self, value_a, value_b, name=None): 91 | """ 92 | Método que adiciona uma aresta ao grafo. 93 | 94 | Parâmetros: 95 | ---------- 96 | value_a: 97 | - Identificador do vértice cabeça da aresta. 98 | value_b: 99 | - Identificador do vértice cauda da aresta. 100 | name: String 101 | - Nome da aresta do grafo. 102 | """ 103 | vertex_a = self.vertices.get(value_a) 104 | vertex_b = self.vertices.get(value_b) 105 | 106 | if vertex_a is None or vertex_b is None: 107 | raise VertexNotExistsException() 108 | 109 | if self.edge_name_exists(name): 110 | raise EdgeNameExistsException() 111 | 112 | new_edge = SimpleEdge(name=name, vertex_a=vertex_a, vertex_b=vertex_b) 113 | 114 | self.edges.append(new_edge) 115 | return self.show_edge(value_a, value_b) 116 | 117 | def edge_name_exists(self, name): 118 | for edge in self.edges: 119 | if edge.get_name() == name: 120 | return True 121 | return False 122 | 123 | def delete_edge(self, value_a, value_b): 124 | """ 125 | Método que remove uma aresta do grafo. 126 | 127 | Parâmetros: 128 | ---------- 129 | value_a: 130 | - Identificador do vértice cabeça da aresta. 131 | value_b: 132 | - Identificador do vértice cauda da aresta. 133 | """ 134 | vertex_a = self.vertices.get(value_a) 135 | vertex_b = self.vertices.get(value_b) 136 | edge_aux = SimpleEdge(vertex_a=vertex_a, vertex_b=vertex_b) 137 | 138 | edge_out = None 139 | if self.edges.__contains__(edge_aux): 140 | index = self.edges.index(edge_aux) 141 | edge_out = self.edges[index] 142 | self.edges.remove(edge_aux) 143 | else: 144 | raise EdgeNotFoundException() 145 | 146 | return edge_out 147 | 148 | def is_terminal(self, edge, value): 149 | """ 150 | Método que verifica se um dado vértice é terminal de uma 151 | dada aresta. 152 | 153 | Parâmetros: 154 | ---------- 155 | edge: SimpleEdge 156 | - Aresta a ser verificada. 157 | value: 158 | - Identificador do vertice. 159 | 160 | Retorno: 161 | ---------- 162 | resultado: bool 163 | - Valor booleano indicando se o vértice é um dos terminais 164 | da aresta. 165 | """ 166 | return edge.vertex_a.value == value or edge.vertex_b.value == value 167 | 168 | def num_vertex(self): 169 | """ 170 | Método que retorna o número de vértices no grafo. 171 | 172 | Retorno: 173 | ---------- 174 | Quantidade: Int 175 | - Quantidade de número de vértices. 176 | """ 177 | return len(self.vertices) 178 | 179 | def vertex_exists(self, value): 180 | """ 181 | Método que indica se um determinado vértice pertence ao Grafo. 182 | 183 | Parâmetros: 184 | ---------- 185 | value: 186 | - Identificador do vértice a ser verificado 187 | 188 | Retorno: 189 | ---------- 190 | True: Caso o vertice pertença ao grafo. 191 | 192 | False: Caso não. 193 | """ 194 | return self.vertices.__contains__(value) 195 | 196 | def edge_exists(self, value_a, value_b): 197 | """ 198 | Método booleano que indica se um determinada aresta pertence 199 | ao Grafo. 200 | 201 | Parâmetros: 202 | ---------- 203 | value_a: 204 | - Identificador do vértice cabeça da aresta. 205 | value_b: 206 | - Identificador do vértice cauda da aresta. 207 | 208 | Retorno: 209 | ---------- 210 | True: caso a aresta exista. 211 | 212 | False: caso contrário. 213 | """ 214 | vertex_a = self.vertices.get(value_a) 215 | vertex_b = self.vertices.get(value_b) 216 | edge_aux = SimpleEdge(vertex_a=vertex_a, vertex_b=vertex_b) 217 | 218 | if self.edges.__contains__(edge_aux): 219 | return True 220 | else: 221 | return False 222 | 223 | def num_edges(self): 224 | """ 225 | Método que retorna o número de arestas no grafo. 226 | 227 | Retorno: 228 | ---------- 229 | Quantidade: Int 230 | - Quantidade de número de arestas. 231 | """ 232 | return len(self.edges) 233 | 234 | def vertex_neighbors(self, value): 235 | """ 236 | Método que encontra vertices vizinhos do vertice de entrada. 237 | 238 | Parâmetros: 239 | ---------- 240 | value: 241 | - Identificador do vertice. 242 | 243 | Retorno: 244 | ---------- 245 | neigh_vertices: List 246 | - Lista de vertices. 247 | """ 248 | if self.vertex_exists(value): 249 | neigh_vertices = [] 250 | for edge in self.edges: 251 | if edge.vertex_a.value == value: 252 | neigh_vertices.append(edge.vertex_b) 253 | elif edge.vertex_b.value == value: 254 | neigh_vertices.append(edge.vertex_a) 255 | return neigh_vertices 256 | else: 257 | raise VertexNotExistsException() 258 | 259 | def vertex_degree(self, value): 260 | """ 261 | Método que retorna o grau do vértice de entrada. 262 | 263 | Parâmetros: 264 | ---------- 265 | value: 266 | - Identificador do vertice. 267 | 268 | Retorno: 269 | ---------- 270 | Grau: Int 271 | - Grau do vértice de entrada. 272 | """ 273 | if self.vertex_exists(value): 274 | return len(self.vertex_neighbors(value)) 275 | else: 276 | raise VertexNotExistsException() 277 | 278 | def is_vertices_adjacents(self, value_a, value_b): 279 | """ 280 | Método que indica se os vértices de entrada são adjacentes. 281 | 282 | Parâmetros: 283 | ---------- 284 | value_a: 285 | - Identificador do vértice. 286 | value_b: 287 | - Identificador do vértice. 288 | 289 | Retorno: 290 | ---------- 291 | True: Caso os vertices sejam adjacentes. 292 | 293 | False: Caso contrario. 294 | """ 295 | neigh_vertices = self.vertex_neighbors(value_a) 296 | vertex_b = self.vertices.get(value_b) 297 | if vertex_b in neigh_vertices: 298 | return True 299 | else: 300 | return False 301 | 302 | def get_all_vertex(self): 303 | """ 304 | Método que retorna uma lista com os vértices do grafo. 305 | 306 | Retorno: 307 | ---------- 308 | vertices: List 309 | - Lista com todos os vértices do grafo. 310 | """ 311 | return self.vertices 312 | 313 | def list_graph_vertices(self): 314 | """ 315 | Método que retorna lista com todos os identificadores dos 316 | vértices do grafo. 317 | 318 | Retorno: 319 | ---------- 320 | vertices: List 321 | - Lista com o nome de todas os vértices do grafo. 322 | """ 323 | vertices = [] 324 | for vertex in self.vertices: 325 | vertices.append(vertex) 326 | return vertices 327 | 328 | def list_graph_edges(self): 329 | """ 330 | Método que retorna lista com todos os nomes as arestas 331 | do grafo. 332 | 333 | Retorno: 334 | ---------- 335 | edges: List 336 | - Lista com o nome de todas as arestas do grafo. 337 | """ 338 | edges = [] 339 | for edge in self.edges: 340 | edges.append(edge.name) 341 | return edges 342 | 343 | def cycle(self, v, visited, parent): 344 | """ 345 | Método que verifica se tem ciclo no subgrafo a partir 346 | do vértice v. 347 | 348 | Parâmetros: 349 | ---------- 350 | v: 351 | - Vértice. 352 | visited: 353 | - Lista de vértices já visitados. 354 | parent: 355 | - Pai do vértice atual. 356 | 357 | Retorno: 358 | ---------- 359 | True: se o subgrafo possuir um loop. 360 | 361 | False: caso não possua. 362 | """ 363 | visited[v] = True 364 | 365 | for i in self.vertices: 366 | if(self.is_vertices_adjacents(v, i)): 367 | if visited[i] is False: 368 | if(self.cycle(i, visited, v)): 369 | return True 370 | elif parent != i: 371 | return True 372 | return False 373 | 374 | def has_cycle(self): 375 | """ 376 | Método que verifica se o grafo possui um ciclo. 377 | Loops também são detectados. 378 | 379 | Retorno: 380 | ---------- 381 | True: se gráfo possuir ciclo ou loop. 382 | 383 | False: caso nao possua. 384 | """ 385 | visited = dict() 386 | 387 | for i in self.vertices: 388 | visited[i] = False 389 | 390 | for i in self.vertices: 391 | if visited[i] is False: 392 | if(self.cycle(i, visited, -1)) is True: 393 | return True 394 | return False 395 | 396 | def has_loop(self): 397 | """ 398 | Método que verifica se o grafo possui um loop. 399 | 400 | Retorno: 401 | ---------- 402 | True: se gráfo possuir loop. 403 | 404 | False: caso nao possua. 405 | """ 406 | for edge in self.edges: 407 | if edge.is_loop(): 408 | return True 409 | return False 410 | 411 | def check_regular_graph(self): 412 | """ 413 | Método que verifica a regularidade de um grafo. 414 | 415 | Retorno: 416 | ---------- 417 | True: Se o grafo for regular. 418 | 419 | False: Se o grafo não for regular. 420 | """ 421 | valency = [] 422 | 423 | for i in self.vertices: 424 | v = 0 425 | aux = SimpleVertex(i) 426 | for j in self.edges: 427 | if aux == j.vertex_a or aux == j.vertex_b: 428 | v += 1 429 | valency.append(v) 430 | return len(set(valency)) <= 1 431 | 432 | def incidence_list(self): 433 | """ 434 | Método que retorna uma lista de objetos que contem 435 | a incidencia dos vertices com as arestas. 436 | 437 | Retorno: 438 | ---------- 439 | incidence_list: List 440 | - Lista com os objetos de ligação(ValueBinding). 441 | """ 442 | incidence_list = [] 443 | for v in self.vertices.values(): 444 | for e in self.edges: 445 | if e.vertex_a == v and e.vertex_b == v: 446 | incidence_list.append( 447 | ValueBinding(v.get_value(), e.get_name(), 2) 448 | ) 449 | elif e.vertex_a == v or e.vertex_b == v: 450 | incidence_list.append( 451 | ValueBinding(v.get_value(), e.get_name(), 1) 452 | ) 453 | else: 454 | incidence_list.append( 455 | ValueBinding(v.get_value(), e.get_name(), 0) 456 | ) 457 | return incidence_list 458 | 459 | def adjacency_matrix(self): 460 | """ 461 | Método que retorna a representação em forma de 462 | matriz de adjacência do grafo. 463 | 464 | Retorno: 465 | ---------- 466 | adjacency_matrix: Dict 467 | - Dicionario que representa o grafo no formato 468 | matriz de adjacência. 469 | """ 470 | adjacency_matrix = dict() 471 | for value in self.vertices.keys(): 472 | adjacency_matrix[value] = dict() 473 | 474 | for vertex in self.vertices.keys(): 475 | adjacency_matrix[value][vertex] = 0 476 | 477 | for edge in self.edges: 478 | value_a = edge.vertex_a.get_value() 479 | value_b = edge.vertex_b.get_value() 480 | adjacency_matrix[value_a][value_b] += 1 481 | adjacency_matrix[value_b][value_a] += 1 482 | 483 | return adjacency_matrix 484 | 485 | def __str__(self): 486 | """ 487 | Método que retorna a representação textual do grafo. 488 | 489 | Retorno: 490 | ---------- 491 | graph_string: String 492 | - Representação textual do grafo. 493 | """ 494 | graph_string = "" 495 | for edge in self.edges: 496 | graph_string += edge.__str__() 497 | graph_string += "\n" 498 | return graph_string 499 | -------------------------------------------------------------------------------- /py_graph_t/SimpleGraph.py: -------------------------------------------------------------------------------- 1 | from .edges.SimpleEdge import SimpleEdge 2 | from .Graph import Graph 3 | 4 | from .exceptions.SimpleGraphException import ( 5 | VertexNotExistsException, 6 | EdgeDuplicatedException, 7 | LoopDetectedException 8 | ) 9 | 10 | 11 | class SimpleGraph(Graph): 12 | """ 13 | Implementação de um Grafo Simples. 14 | 15 | Um grafo simples ``não contém``: 16 | - Loops 17 | - Arestas paralelas 18 | 19 | Nessa implementação as ``arestas não tem pesos``. 20 | """ 21 | 22 | def __init__(self): 23 | super().__init__() 24 | pass 25 | 26 | def add_edge(self, value_a, value_b, name=None): 27 | """ 28 | Método que adiciona uma aresta ao grafo. 29 | 30 | Parâmetros: 31 | ---------- 32 | value_a: 33 | - Identificador do vértice cabeça da aresta. 34 | value_b: 35 | - Identificador do vértice cauda da aresta. 36 | name: String 37 | - Nome da aresta do grafo. 38 | """ 39 | 40 | if value_a == value_b: 41 | raise LoopDetectedException() 42 | 43 | vertex_a = self.vertices.get(value_a) 44 | vertex_b = self.vertices.get(value_b) 45 | new_edge = SimpleEdge(name=name, vertex_a=vertex_a, vertex_b=vertex_b) 46 | 47 | if vertex_a is None or vertex_b is None: 48 | raise VertexNotExistsException() 49 | 50 | if new_edge in self.edges: 51 | raise EdgeDuplicatedException() 52 | 53 | self.edges.append(new_edge) 54 | return self.show_edge(value_a, value_b) 55 | -------------------------------------------------------------------------------- /py_graph_t/__init__.py: -------------------------------------------------------------------------------- 1 | from .Graph import Graph 2 | from .SimpleGraph import SimpleGraph 3 | from .CompleteGraph import CompleteGraph 4 | -------------------------------------------------------------------------------- /py_graph_t/edges/SimpleEdge.py: -------------------------------------------------------------------------------- 1 | class SimpleEdge(object): 2 | """Classe para criação de arestas.""" 3 | vertex_a = None 4 | vertex_b = None 5 | name = None 6 | 7 | def __init__(self, name=None, vertex_a=None, vertex_b=None): 8 | """ Inicialização dos atributos da classe SimpleEdge.""" 9 | if name is None: 10 | name = vertex_a.value.__str__() + vertex_b.value.__str__() 11 | self.name = name 12 | self.vertex_a = vertex_a 13 | self.vertex_b = vertex_b 14 | 15 | def get_name(self): 16 | return self.name 17 | 18 | def is_loop(self): 19 | """ 20 | Método para verificar se aresta representa um loop. 21 | Um loop é uma aresta que conecta um vértice a ele mesmo. 22 | """ 23 | return self.vertex_a == self.vertex_b 24 | 25 | def __eq__(self, other): 26 | """ 27 | Método para comparação de duas arestas 28 | 29 | Parâmetros: 30 | --------- 31 | other: SimpleEdge 32 | - aresta a ser comparada 33 | """ 34 | if isinstance(other, self.__class__): 35 | result1 = self.vertex_a == other.vertex_a and \ 36 | self.vertex_b == other.vertex_b 37 | result2 = self.vertex_b == other.vertex_a and \ 38 | self.vertex_a == other.vertex_b 39 | return result1 or result2 40 | else: 41 | return False 42 | 43 | def __str__(self): 44 | return str(self.name) + ": " + \ 45 | self.vertex_a.__str__() + " -> " + \ 46 | self.vertex_b.__str__() 47 | 48 | def __repr__(self): 49 | return str(self) 50 | -------------------------------------------------------------------------------- /py_graph_t/edges/__init__.py: -------------------------------------------------------------------------------- 1 | from .SimpleEdge import SimpleEdge 2 | -------------------------------------------------------------------------------- /py_graph_t/exceptions/SimpleGraphException.py: -------------------------------------------------------------------------------- 1 | class VertexNotExistsException(Exception): 2 | def __str__(self): 3 | return "Vértice não existe" 4 | 5 | 6 | class EdgeDuplicatedException(Exception): 7 | def __str__(self): 8 | return "Aresta duplicada" 9 | 10 | 11 | class EdgeNotFoundException(Exception): 12 | def __str__(self): 13 | return "Aresta não existe" 14 | 15 | 16 | class VertexDuplicatedException(Exception): 17 | def __str__(self): 18 | return "Vértice duplicado" 19 | 20 | 21 | class CycleDetectedException(Exception): 22 | def __str__(self): 23 | return "Esse tipo de grafo não pode conter ciclo" 24 | 25 | 26 | class LoopDetectedException(Exception): 27 | def __str__(self): 28 | return "Esse tipo de grafo não pode conter loops" 29 | 30 | 31 | class EdgeNameExistsException(Exception): 32 | def __str__(self): 33 | return "Aresta com esse nome já existe" 34 | -------------------------------------------------------------------------------- /py_graph_t/exceptions/__init__.py: -------------------------------------------------------------------------------- 1 | from .SimpleGraphException import * 2 | -------------------------------------------------------------------------------- /py_graph_t/util/ValueBinding.py: -------------------------------------------------------------------------------- 1 | class ValueBinding: 2 | """ 3 | Classe que representa uma ligação de incidência de um 4 | vértice e a aresta de um grafo. 5 | """ 6 | 7 | def __init__(self, vertex_name, edge_name, value): 8 | """ 9 | Inicialização dos atributos da classe ValueBinding. 10 | """ 11 | self.vertex_name = vertex_name 12 | self.edge_name = edge_name 13 | self.value = value 14 | 15 | def get_vertex_name(self): 16 | return self.vertex_name 17 | 18 | def get_edge_name(self): 19 | return self.edge_name 20 | 21 | def get_value(self): 22 | return self.value 23 | 24 | def __eq__(self, other): 25 | """ 26 | Método para comparação de duas arestas 27 | 28 | Parâmetros: 29 | --------- 30 | other: ValueBinding 31 | - aresta a ser comparada 32 | """ 33 | if isinstance(other, self.__class__): 34 | return self.__dict__ == other.__dict__ 35 | else: 36 | return False 37 | 38 | def __repr__(self): 39 | result = str(self.vertex_name) + " - " 40 | result += str(self.edge_name) + " => " 41 | result += str(self.value) 42 | return result 43 | -------------------------------------------------------------------------------- /py_graph_t/util/__init__.py: -------------------------------------------------------------------------------- 1 | from .ValueBinding import ValueBinding 2 | -------------------------------------------------------------------------------- /py_graph_t/vertex/SimpleVertex.py: -------------------------------------------------------------------------------- 1 | class SimpleVertex(): 2 | """Implementação de um simples vértice.""" 3 | value = None 4 | 5 | def __init__(self, value): 6 | """ 7 | Construtor da classe simpleVertex. 8 | 9 | Parâmetros: 10 | ---------- 11 | value: Um tipo existente ou criado por você. 12 | - Valor a ser colocado no vértice. 13 | """ 14 | self.value = value 15 | 16 | def get_value(self): 17 | return self.value 18 | 19 | def set_value(self, new_value): 20 | """ 21 | Método que altera o valor do vértice. 22 | 23 | Parâmetros: 24 | ---------- 25 | value: Um tipo existente ou criado por você 26 | - Valor a ser alterado no vértice. 27 | """ 28 | self.value = new_value 29 | 30 | def __eq__(self, other): 31 | if isinstance(other, self.__class__): 32 | return self.__dict__ == other.__dict__ 33 | else: 34 | return False 35 | 36 | def __str__(self): 37 | return "Vértice {}".format(self.value) 38 | 39 | def __repr__(self): 40 | return str(self) 41 | -------------------------------------------------------------------------------- /py_graph_t/vertex/__init__.py: -------------------------------------------------------------------------------- 1 | from .SimpleVertex import SimpleVertex 2 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "pygraph" 3 | version = "0.1.0" 4 | description = "Biblioteca com intuito de implementar os grafos e seus \\" 5 | authors = ["algoritmos de Teoria dos Grafos."] 6 | license = "MIT" 7 | 8 | [tool.poetry.dependencies] 9 | python = "^3.8" 10 | 11 | [tool.poetry.dev-dependencies] 12 | pytest = "^6.0.1" 13 | pytest-watch = "^4.2.0" 14 | flake8 = "^3.8.3" 15 | 16 | [build-system] 17 | requires = ["poetry>=0.12"] 18 | build-backend = "poetry.masonry.api" 19 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.md 3 | license_file = LICENSE -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | with open("README.md", "r") as fh: 4 | long_description = fh.read() 5 | 6 | setup( 7 | name='PyGraphT', 8 | version='0.1.0', 9 | author='Rich Elton', 10 | author_email='richelton14@gmail.com', 11 | description='Biblioteca com intuito de implementar os grafos e seus \ 12 | algoritmos de Teoria dos Grafos.', 13 | long_description=long_description, 14 | long_description_content_type="text/markdown", 15 | include_package_data=True, 16 | packages=find_packages(), 17 | url="https://github.com/richecr/PyGraph", 18 | project_urls={ 19 | 'Código fonte': 'https://github.com/richecr/PyGraph', 20 | }, 21 | keywords='graph theory algorithms', 22 | license='MIT' 23 | ) 24 | --------------------------------------------------------------------------------