Browse Source

Merge pull request #25 from Jammyjamjamman/graphs_py

Added graphs python code
pull/33/head
Jeffery Russell 5 years ago
committed by GitHub
parent
commit
a7ef5dd476
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 122 additions and 0 deletions
  1. +122
    -0
      graphing/graph.py

+ 122
- 0
graphing/graph.py View File

@ -0,0 +1,122 @@
"""
:Author: James Sherratt
:Date: 20/10/2019
:License: MIT
:name: graph.py
"""
class Graph:
def __init__(self):
self.vertices = set()
self.edges = set()
def add_vertex(self, vert):
"""
Add a vertex to the graph.
:param vert: name of the vertex.
:return: None
"""
self.vertices.add(vert)
def add_edge(self, vert1, vert2, directional=False):
"""
Add an edge to the graph. The edge will be defined as a simple tuple where:
- The first value is the initial edge.
- The second is the final edge.
- The third is whether the edge is directional.
:param vert1: the start vertex.
:param vert2: the end vertex.
:param directional: whether or not the edge has a direction. Default: False
:return: None
"""
self.vertices.add(vert1)
self.vertices.add(vert2)
if (not directional) and (vert1 > vert2):
# swap if not directional to avoid duplicates in the set.
self.edges.add((vert2, vert1, directional))
else:
self.edges.add((vert1, vert2, directional))
def adjacency(self, vert1, vert2):
"""
Check if 2 vertices are adjacent (if they exist). Note: if vert1 and vert2
are connected, but directionally from vert2 to vert1, False is returned.
:param vert1: The first vertex to compare.
:param vert2: The second vertex to compare.
:return: True if adjacent, False if not, None if either are not in the set.
"""
if (vert1 not in self.vertices) or (vert2 not in self.vertices):
return None
for edge in self.edges:
if (vert1 == edge[0]) and (vert2 == edge[1]):
return True
if (not edge[2]) and ((vert1 == edge[1]) and (vert2 == edge[0])):
return True
return False
def neighbours(self, vert):
"""
Get the neighbours of a vertex.
:param vert: name of the vertex.
:return: list of neighbours, or None if the vertex is not in the graph.
"""
if vert not in self.vertices:
return None
neighbours = set()
for edge in self.edges:
if vert == edge[0]:
neighbours.add(edge[1])
elif (not edge[2]) and (vert == edge[1]):
neighbours.add(edge[0])
return neighbours
def as_dict(self):
"""
Convert the graph to a dictionary where:
- Each key is a vertex.
- Each value is a set of neighbours you can travel to.
:return: dict representing the graph.
"""
graph_dict = {v: set() for v in self.vertices}
for edge in self.edges:
graph_dict[edge[0]].add(edge[1])
if not edge[2]:
graph_dict[edge[1]].add(edge[0])
return graph_dict
if __name__ == "__main__":
mygraph = Graph()
mygraph.add_edge("a", "b")
mygraph.add_edge("b", "c")
mygraph.add_edge("b", "d")
mygraph.add_edge("c", "b")
mygraph.add_edge("a", "e", directional=True)
mygraph.add_vertex("z")
print("b neighbours:", mygraph.neighbours("b"))
print("a neighbours:", mygraph.neighbours("a"))
print("q neighbours:", mygraph.neighbours("q"))
print("e neighbours:", mygraph.neighbours("e"))
print()
# Adjacency has direction.
print("a and e adjacent:", mygraph.adjacency("a", "e"))
print("e and a adjacent:", mygraph.adjacency("e", "a"))
print("d and b adjacent", mygraph.adjacency("d", "b"))
print("q and a adjacent:", mygraph.adjacency("q", "a"))
print("z and a adjacent:", mygraph.adjacency("z", "a"))
print()
print("as dict")
print(mygraph.as_dict())
# Exercise/ project: add a method "path" to find path between 2 vertices.
# (Hint: lookup DFS/ BFS algorithm.)

Loading…
Cancel
Save