Como representar nitidamente um gráfico em Python ? (Começando do zero, ou seja, sem bibliotecas!)
Qual estrutura de dados (por exemplo, dicts / tuplas / dict (tuplas)) será rápida, mas também eficiente em termos de memória?
Deve-se ser capaz de fazer várias operações gráficas nele.
Como apontado, as várias representações gráficas podem ajudar. Como fazer para implementá-los em Python?
Quanto às bibliotecas, essa pergunta tem respostas bastante boas.
python
data-structures
graph
shad0w_wa1k3r
fonte
fonte
dict
delist
s. Basicamente, algo parecido{<parent>: [<child>, ...], ...}
.Respostas:
Embora esta seja uma pergunta um tanto antiga, pensei em dar uma resposta prática para qualquer um que topasse com isso.
Digamos que você obtenha seus dados de entrada para suas conexões como uma lista de tuplas, assim:
A estrutura de dados que descobri ser mais útil e eficiente para gráficos em Python é um conjunto de conjuntos . Essa será a estrutura básica de nossa
Graph
classe. Você também deve saber se essas conexões são arcos (direcionados, conectar em uma direção) ou bordas (não direcionadas, conectar em ambos os sentidos). Cuidaremos disso adicionando umdirected
parâmetro aoGraph.__init__
método. Também adicionaremos alguns outros métodos úteis.Vou deixar como um "exercício para o leitor" para criar um
find_shortest_path
e outros métodos.Vamos ver isso em ação ...
fonte
heapq
biblioteca para empilhar listas de tuplas em vez de conjuntos. Por exemplo, o gráfico seria um dicionário de pilhas como:_graph = {'A': heapify([(0.3, 'D'), (0.5, 'B'), (0.75, 'A'), (0.9, 'C')])}
(nota: você não usariaheapify
assim, leia a ajuda da biblioteca), então você poderia usar asheapq
funções para inserir e obter as arestas ponderadas.log
acesso de tempo. Mas como estender o dicionário que você usou para mapear nodeID e weight?NetworkX é uma biblioteca de gráficos Python incrível. Você terá dificuldade em encontrar algo que você precisa e ainda não.
E é um código aberto, então você pode ver como eles implementaram seus algoritmos. Você também pode adicionar algoritmos adicionais.
https://github.com/networkx/networkx/tree/master/networkx/algorithms
fonte
graph.py --> class Graph
. E tudo o que quero ver é como eles usam__iter__
.Primeiro, a escolha da lista clássica em comparação com as representações de matriz depende do propósito (o que você quer fazer com a representação). Os problemas e algoritmos bem conhecidos estão relacionados à escolha. A escolha do tipo de representação abstrata dita como ela deve ser implementada.
Em segundo lugar, a questão é se os vértices e arestas devem ser expressos apenas em termos de existência ou se eles carregam alguma informação extra.
Do ponto de vista dos tipos de dados integrados do Python, qualquer valor contido em outro lugar é expresso como uma referência (oculta) ao objeto de destino. Se for uma variável (isto é, referência nomeada), então o nome e a referência são sempre armazenados em um dicionário (interno). Se você não precisa de nomes, a referência pode ser armazenada em seu próprio contêiner - aqui provavelmente a lista Python sempre será usada para a lista como abstração.
A lista Python é implementada como uma matriz dinâmica de referências, a tupla Python é implementada como uma matriz estática de referências com conteúdo constante (o valor das referências não pode ser alterado). Por isso, eles podem ser facilmente indexados. Dessa forma, a lista pode ser utilizada também para implementação de matrizes.
Outra forma de representar matrizes são os arrays implementados pelo módulo padrão
array
- mais restritos em relação ao tipo armazenado, valor homogêneo. Os elementos armazenam o valor diretamente. (A lista armazena as referências aos objetos de valor). Dessa forma, é mais eficiente em termos de memória e também o acesso ao valor é mais rápido.Às vezes, você pode achar útil uma representação ainda mais restrita, como
bytearray
.fonte
Existem duas excelentes bibliotecas de gráficos NetworkX e igraph . Você pode encontrar os dois códigos-fonte da biblioteca no GitHub. Você sempre pode ver como as funções são escritas. Mas eu prefiro NetworkX porque é fácil de entender.
Veja seus códigos para saber como eles fazem as funções. Você terá várias ideias e poderá escolher como deseja fazer um gráfico usando estruturas de dados.
fonte