|
|
- """
- :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.)
|