SlideShare a Scribd company logo
In this assignment, you will work with graphs. Begin with the "useGraph.py" starter file. This
file contains comment instructions that tell you where to add your code to do various tasks that
use and manipulate graphs. Make sure you read the "Programming Activity 8 - Guidance"
document. Make sure your output matches the "Programming Activity 8 - Expected Output"
document.
""" File: useGraph.py
Author: Derrf Seitz
This program exercises graphs.
The following files must be in the same folder:
abstractcollection.py
graph.py
"""
# # Replace with your name.
# Replace any "" comments with your own code statement(s)
# to accomplish the specified task.
# DO NOT CHANGE ANY OTHER CODE. from graph import LinkedDirectedGraph
# Part 1:
# Complete the following function: def topologicalSort(graph):
<your code>
# graph = LinkedDirectedGraph()
# The graph represents the following course prerequisites:
# A requires nothing
# B requires nothing
# C requires A
# D requires A, B, and C
# E requires C
# F requires B and D
# G requires E and F
# H requires C, F, and G
# Part 2:
# Add the vertices:
<your code>
# Part 3:
# Add the edges:
<your code>
# print("Graph:") print(graph) print() print("Courses:")
# Part 4:
# Display each vertex on a separate line:
<your code>
# print()
print("Prerequisites:")
# Part 5:
# Display each edge on a separate line:
<your code>
# print()
print("One possible order to take the courses:")
# Part 6:
# Display the courses in prerequisite (topological) order:
<your code>
# print()
"""
File: graph.py
Author: Ken Lambert, copyright 2015, 2020
Used by permission.
Adds the in, +, ==, and clone operations to support graph-specific behavior.
"""
from abstractcollection import AbstractCollection
class LinkedEdge(object):
# An edge has a source vertex, a destination vertex,
# a weight, and a mark attribute.
# Constructor
def __init__(self, fromVertex, toVertex, weight = None):
self.vertex1 = fromVertex
self.vertex2 = toVertex
self.weight = weight
self.mark = False
# Accessor methods
def __eq__(self, other):
"""Two edges are equal if they connect
the same vertices."""
if self is other:
return True
if type(self) != type(other):
return False
return self.vertex1 == other.vertex1 and 
self.vertex2 == other.vertex2
def __hash__(self): # Derrf Seitz 11/16/2020
"""Hash method for an edge."""
return hash(self.vertex1.label + self.vertex2.label)
def __str__(self):
"""Returns the string representation of the edge."""
return str(self.vertex1) + ">" + 
str(self.vertex2) + ":" + 
str(self.weight)
def getFromVertex(self): # Derrf Seitz 12/17/2015
"""Returns the edge's origin vertex."""
return self.vertex1
def getOtherVertex(self, thisVertex):
"""Returns the vertex opposite thisVertex."""
if thisVertex == None or thisVertex == self.vertex2:
return self.vertex1
else:
return self.vertex2
def getToVertex(self):
"""Returns the edge's destination vertex."""
return self.vertex2
def getWeight(self):
"""Returns the edge's weight."""
return self.weight
def isMarked(self):
"""Returns True if the edge is marked
or False otherwise."""
return self.mark
# Mutator methods
def clearMark(self):
"""Clears the mark on the edge."""
self.mark = False
def setMark(self):
"""Sets the mark on the edge."""
self.mark = True
def setWeight(self, weight):
"""Sets the weight on the edge to weight."""
self.weight = weight
class LinkedVertex(object):
# A vertex has a label, a list of incident edges,
# and a mark attribute.
# Constructor
def __init__(self, label):
self.label = label
self.edgeList = list()
self.mark = False
# Accessor methods
def __eq__(self, other):
"""Two vertices are equal if they have
the same labels."""
if self is other:
return True
if type(self) != type(other):
return False
return self.getLabel() == other.getLabel()
def __hash__(self): # Derrf Seitz 12/16/2015
"""Hash method for a vertex."""
return hash(self.label)
def __str__(self):
"""Returns the string representation of the vertex."""
return str(self.label)
def getEdgeTo(self, toVertex):
"""Returns the connecting edge if it exists, or
None otherwise."""
edge = LinkedEdge(self, toVertex)
try:
return self.edgeList[self.edgeList.index(edge)]
except:
return None
def getLabel(self):
"""Returns the label of the vertex."""
return self.label
def incidentEdges(self):
"""Returns the incident edges of this vertex."""
return iter(self.edgeList)
def isMarked(self):
"""Returns True if the vertex is marked
or False otherwise."""
return self.mark
def neighboringVertices(self):
"""Returns the neighboring vertices of this vertex."""
vertices = list()
for edge in self.edgeList:
vertices.append(edge.getOtherVertex(self))
return iter(vertices)
# Mutator methods
def addEdgeTo(self, toVertex, weight):
"""Connects the vertices with an edge."""
edge = LinkedEdge(self, toVertex, weight)
self.edgeList.append(edge)
def clearMark(self):
"""Clears the mark on the vertex."""
self.mark = False;
def removeEdgeTo(self, toVertex):
"""Returns True if the edge exists and is removed,
or False otherwise."""
edge = LinkedEdge(self, toVertex)
if edge in self.edgeList:
self.edgeList.remove(edge)
return True
else:
return False
def setLabel(self, label, g):
"""Sets the vertex's label to label."""
g.vertices.pop(self.label, None)
g.vertices[label] = self
self.label = label
def setMark(self):
"""Sets the mark on the vertex."""
self.mark = True
class LinkedDirectedGraph(AbstractCollection):
# A graph has a count of vertices, a count of edges,
# and a dictionary of label/vertex pairs.
# Class variables
INTERFACE = "GraphInterface"
# Constructor
def __init__(self, sourceCollection = None):
self.edgeCount = 0
self.vertices = dict() # Dictionary of vertices
AbstractCollection.__init__(self, sourceCollection)
# Accessor methods
def __contains__(self, item):
"""Returns True if item is a label in a vertex,
or False otherwise."""
for vertex in self:
if vertex.getLabel() == item:
return True
return False
def __eq__(self, other):
"""Returns True if self and other are identical, or
True if self and other are of the same type, have the
same number of vertices, and these vertices are connected
in the same manner (including same labels and edge weights)."""
# Check simple criteria first
if self is other:
return True
if type(self) != type(other):
return False
if len(self) != len(other):
return False
for vertex in self:
# All vertex labels must match
if not vertex.getLabel() in other:
print("Mismatched vertices")
return False
# Vertices with the same labels must have the same
# incident edges
otherVertex = other.getVertex(vertex.getLabel())
selfEdges = list(vertex.incidentEdges())
otherEdges = list(otherVertex.incidentEdges())
if len(selfEdges) != len(otherEdges):
return False
for edge in selfEdges:
found = False
for otherEdge in otherEdges:
if edge == otherEdge and 
edge.getWeight() == otherEdge.getWeight():
found = True
break
if not found: return False
return True
def __iter__(self):
"""Supports iteration over a view of self (the vertices)."""
return self.getVertices()
def __str__(self):
"""Returns the string representation of the graph."""
result = str(len(self)) + " Vertices: "
for vertex in self.vertices:
result += " " + str(vertex)
result += "n";
result += str(self.sizeEdges()) + " Edges: "
for edge in self.edges():
result += " " + str(edge)
return result
def containsEdge(self, fromLabel, toLabel):
"""Returns True if an edge connects the vertices,
or False otherwise."""
return self.getEdge(fromLabel, toLabel) != None
def containsVertex (self, label):
return label in self.vertices
def clone(self):
"""Returns an exact copy of self, including vertex labels,
edges connecting vertices, and edge weights."""
newGraph = type(self)(map(lambda vertex: vertex.getLabel(), self))
for vertex in self:
for neighbor in vertex.neighboringVertices():
edge = vertex.getEdgeTo(neighbor)
newGraph.addEdge(vertex.getLabel(),
neighbor.getLabel(),
edge.getWeight())
return newGraph
def edges(self):
"""Supports iteration over the edges in the graph."""
result = set()
for vertex in self.getVertices():
edges = vertex.incidentEdges()
result = result.union(set(edges))
return iter(result)
def getEdge(self, fromLabel, toLabel):
"""Returns the edge connecting the two vertices, or None if
no edge exists.
Precondition: vertices with fromLabel and toLabel must
already be in the graph.
Raises: AttibuteError if the vertices
are not already in the graph."""
fromVertex = self.getVertex(fromLabel)
toVertex = self.getVertex(toLabel)
return fromVertex.getEdgeTo(toVertex)
def getVertex(self, label):
"""Precondition: a vertex with label must already be in the graph.
Raises: AttibuteError if a vertex with label is not already in the graph."""
if not self.containsVertex(label):
raise AttributeError("Label " + str(label) + " not in graph.""")
return self.vertices[label]
def getVertices(self):
"""Supports iteration over the vertices in the graph."""
return iter(self.vertices.values())
def incidentEdges(self, label):
"""Supports iteration over the incident edges of the
given verrtex.
Precondition: a vertex with label must already be in the graph.
Raises: AttibuteError if a vertex with label is not already in the graph."""
return self.getVertex(label).incidentEdges()
def neighboringVertices(self, label):
"""Supports iteration over the neighboring vertices of the
given verrtex.
Precondition: a vertex with label must already be in the graph.
Raises: AttibuteError if a vertex with label is not already in the graph."""
return self.getVertex(label).neighboringVertices()
def sizeEdges(self):
"""Returns the number of edges."""
return self.edgeCount
def sizeVertices(self):
"""Returns the number of vertices."""
return len(self)
# Mutator methods
def __add__(self, other):
"""Returns a new collection consisting of the
items in self and other. This will be a graph with
the contents of the operand graphs as separate components.
Precondition: the labels in the two graph operands are disjoint.
Raises: AttributeError if the labels in the two operand graphs
are not disjoint."""
newGraph = self.clone()
for vertex in other:
newGraph.add(vertex.getLabel())
for vertex in other:
for neighbor in vertex.neighboringVertices():
edge = vertex.getEdgeTo(neighbor)
newGraph.addEdge(vertex.getLabel(),
neighbor.getLabel(),
edge.getWeight())
return newGraph
def add(self, label):
"""For compatibility with other collections."""
self.addVertex(label)
def addEdge(self, fromLabel, toLabel, weight):
"""Connects the vertices with an edge with the given weight.
Preconditions: vertices with fromLabel and toLabel must
already be in the graph.
The vertices must not already be connected by an edge.
Raises: AttibuteError if the vertices
are not already in the graph or they are already connected."""
fromVertex = self.getVertex(fromLabel)
toVertex = self.getVertex(toLabel)
if self.getEdge(fromLabel, toLabel):
raise AttributeError("An edge already connects " + 
str(fromLabel) + " and " + 
str(toLabel))
fromVertex.addEdgeTo(toVertex, weight)
self.edgeCount += 1
def addVertex(self, label):
"""Precondition: a vertex with label must not
already be in the graph.
Raises: AttibuteError if a vertex with label
is already in the graph."""
if self.containsVertex(label):
raise AttributeError("Label " + str(label) + " already in graph.""")
self.vertices[label] = LinkedVertex(label)
self.size += 1
def clear(self):
"""Clears the graph."""
self.size = 0
self.edgeCount = 0
self.vertices = dict()
def clearEdgeMarks(self):
"""Clears all the edge marks."""
for edge in self.edges():
edge.clearMark()
def clearVertexMarks(self):
"""Clears all the vertex marks."""
for vertex in self.getVertices():
vertex.clearMark()
def removeEdge (self, fromLabel, toLabel):
"""Returns True if the edge was removed, or False otherwise.
Precondition: vertices with fromLabel and toLabel must
already be in the graph.
Raises: AttibuteError if the vertices
are not already in the graph."""
fromVertex = self.getVertex(fromLabel)
toVertex = self.getVertex(toLabel)
edgeRemovedFlg = fromVertex.removeEdgeTo(toVertex)
if edgeRemovedFlg:
self.edgeCount -= 1
return edgeRemovedFlg
def removeVertex(self, label):
"""Returns True if the vertex was removed, or False otherwise."""
removedVertex = self.vertices.pop(label, None)
if removedVertex is None:
return False
# Examine all other vertices to remove edges
# directed at the removed vertex
for vertex in self.getVertices():
if vertex.removeEdgeTo(removedVertex):
self.edgeCount -= 1
# Examine all edges from the removed vertex to others
for edge in removedVertex.incidentEdges():
self.edgeCount -= 1
self.size -= 1
return True
In this assignment- you will work with graphs- Begin with the -useGrap.pdf

More Related Content

PDF
Artificial Intelligence Practical Manual.pdf
PDF
Codeware
PDF
# Imports# Include your imports here, if any are used. import.pdf
PDF
ImplementDijkstra’s algorithm using the graph class you implemente.pdf
PPTX
Code is not text! How graph technologies can help us to understand our code b...
PDF
Twopi.1
PDF
A limited guide to intermediate and advanced Ruby
PDF
Testing Ruby with Rspec (a beginner's guide)
Artificial Intelligence Practical Manual.pdf
Codeware
# Imports# Include your imports here, if any are used. import.pdf
ImplementDijkstra’s algorithm using the graph class you implemente.pdf
Code is not text! How graph technologies can help us to understand our code b...
Twopi.1
A limited guide to intermediate and advanced Ruby
Testing Ruby with Rspec (a beginner's guide)

Similar to In this assignment- you will work with graphs- Begin with the -useGrap.pdf (18)

PPT
Scala idioms
TXT
Sdl Basic
PPTX
Introduction to Client-Side Javascript
PPTX
ES6 in Real Life
PDF
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
PDF
ES6 General Introduction
PDF
Real World Haskell: Lecture 2
PDF
Python speleology
PDF
Data transformation-cheatsheet
PPTX
CS 151 Classes lecture 2
PDF
Ruby Topic Maps Tutorial (2007-10-10)
PDF
Odoo from 7.0 to 8.0 API
PDF
Odoo - From v7 to v8: the new api
KEY
openFrameworks 007 - 3D
PDF
Coffee script
PPTX
Object Oriented Programming Using C++: C++ Namespaces.pptx
PPTX
Chapter 1 MATLAB Fundamentals easy .pptx
PDF
vb.net.pdf
Scala idioms
Sdl Basic
Introduction to Client-Side Javascript
ES6 in Real Life
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
ES6 General Introduction
Real World Haskell: Lecture 2
Python speleology
Data transformation-cheatsheet
CS 151 Classes lecture 2
Ruby Topic Maps Tutorial (2007-10-10)
Odoo from 7.0 to 8.0 API
Odoo - From v7 to v8: the new api
openFrameworks 007 - 3D
Coffee script
Object Oriented Programming Using C++: C++ Namespaces.pptx
Chapter 1 MATLAB Fundamentals easy .pptx
vb.net.pdf
Ad

More from sidkucheria (20)

PDF
In the below figure- the net flux of CO2 from the oceans to the atmosp.pdf
PDF
In Southern blotting- DNA fragments must be nitrocellulose- before blo.pdf
PDF
In the biased coin problem- given a sequence of toss samples Head- Tai.pdf
PDF
In the article by Siedner and Kraemer- the article describes a delay i.pdf
PDF
In the accompanying figure- which section of the graph illustrates the.pdf
PDF
In the 14th century- the bubonic plague killed more than 2-3 of Europe (1).pdf
PDF
In the 1970s- the United States was the largest producer of steel in t.pdf
PDF
In terms of epigenetic regulation of gene expression- acetylated histo.pdf
PDF
In the 19th century- cavalries were still an important part of the Eur.pdf
PDF
In Table 19-1 are listed the average distance from the Sun- r- in Astr.pdf
PDF
In t- s --ana halnw the rell (formed element) indicated by letter A is.pdf
PDF
In spite of the contribution of plasmids to the spread of antibiotic r.pdf
PDF
In some goats- the presence of horns is produced by an autosomal gene.pdf
PDF
In sexual reproduction- (select answer 1) produce genetically diverse.pdf
PDF
In response to Covid- starting in early 2020- the U-S- government ____.pdf
PDF
In R code- for n N- derive the following limit value with detailed pr.pdf
PDF
IN PYTHON PLEASE! Create a script that- when run-checks every second i.pdf
PDF
In prokaryotes some DNA molecules are in the form of Looped linear DNA.pdf
PDF
In project management- the known steps are anticipated- known steps ar.pdf
PDF
In processing a prefix expression- which part of the process was recur.pdf
In the below figure- the net flux of CO2 from the oceans to the atmosp.pdf
In Southern blotting- DNA fragments must be nitrocellulose- before blo.pdf
In the biased coin problem- given a sequence of toss samples Head- Tai.pdf
In the article by Siedner and Kraemer- the article describes a delay i.pdf
In the accompanying figure- which section of the graph illustrates the.pdf
In the 14th century- the bubonic plague killed more than 2-3 of Europe (1).pdf
In the 1970s- the United States was the largest producer of steel in t.pdf
In terms of epigenetic regulation of gene expression- acetylated histo.pdf
In the 19th century- cavalries were still an important part of the Eur.pdf
In Table 19-1 are listed the average distance from the Sun- r- in Astr.pdf
In t- s --ana halnw the rell (formed element) indicated by letter A is.pdf
In spite of the contribution of plasmids to the spread of antibiotic r.pdf
In some goats- the presence of horns is produced by an autosomal gene.pdf
In sexual reproduction- (select answer 1) produce genetically diverse.pdf
In response to Covid- starting in early 2020- the U-S- government ____.pdf
In R code- for n N- derive the following limit value with detailed pr.pdf
IN PYTHON PLEASE! Create a script that- when run-checks every second i.pdf
In prokaryotes some DNA molecules are in the form of Looped linear DNA.pdf
In project management- the known steps are anticipated- known steps ar.pdf
In processing a prefix expression- which part of the process was recur.pdf
Ad

Recently uploaded (20)

PDF
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
PDF
FORM 1 BIOLOGY MIND MAPS and their schemes
PDF
HVAC Specification 2024 according to central public works department
PPTX
202450812 BayCHI UCSC-SV 20250812 v17.pptx
PDF
Weekly quiz Compilation Jan -July 25.pdf
PDF
Vision Prelims GS PYQ Analysis 2011-2022 www.upscpdf.com.pdf
PDF
Empowerment Technology for Senior High School Guide
PPTX
TNA_Presentation-1-Final(SAVE)) (1).pptx
PPTX
History, Philosophy and sociology of education (1).pptx
PDF
Τίμαιος είναι φιλοσοφικός διάλογος του Πλάτωνα
PDF
BP 704 T. NOVEL DRUG DELIVERY SYSTEMS (UNIT 1)
PDF
Computing-Curriculum for Schools in Ghana
PPTX
Computer Architecture Input Output Memory.pptx
PDF
OBE - B.A.(HON'S) IN INTERIOR ARCHITECTURE -Ar.MOHIUDDIN.pdf
PDF
Paper A Mock Exam 9_ Attempt review.pdf.
DOC
Soft-furnishing-By-Architect-A.F.M.Mohiuddin-Akhand.doc
PDF
CISA (Certified Information Systems Auditor) Domain-Wise Summary.pdf
PPTX
Introduction to pro and eukaryotes and differences.pptx
PDF
ChatGPT for Dummies - Pam Baker Ccesa007.pdf
PDF
advance database management system book.pdf
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
FORM 1 BIOLOGY MIND MAPS and their schemes
HVAC Specification 2024 according to central public works department
202450812 BayCHI UCSC-SV 20250812 v17.pptx
Weekly quiz Compilation Jan -July 25.pdf
Vision Prelims GS PYQ Analysis 2011-2022 www.upscpdf.com.pdf
Empowerment Technology for Senior High School Guide
TNA_Presentation-1-Final(SAVE)) (1).pptx
History, Philosophy and sociology of education (1).pptx
Τίμαιος είναι φιλοσοφικός διάλογος του Πλάτωνα
BP 704 T. NOVEL DRUG DELIVERY SYSTEMS (UNIT 1)
Computing-Curriculum for Schools in Ghana
Computer Architecture Input Output Memory.pptx
OBE - B.A.(HON'S) IN INTERIOR ARCHITECTURE -Ar.MOHIUDDIN.pdf
Paper A Mock Exam 9_ Attempt review.pdf.
Soft-furnishing-By-Architect-A.F.M.Mohiuddin-Akhand.doc
CISA (Certified Information Systems Auditor) Domain-Wise Summary.pdf
Introduction to pro and eukaryotes and differences.pptx
ChatGPT for Dummies - Pam Baker Ccesa007.pdf
advance database management system book.pdf

In this assignment- you will work with graphs- Begin with the -useGrap.pdf

  • 1. In this assignment, you will work with graphs. Begin with the "useGraph.py" starter file. This file contains comment instructions that tell you where to add your code to do various tasks that use and manipulate graphs. Make sure you read the "Programming Activity 8 - Guidance" document. Make sure your output matches the "Programming Activity 8 - Expected Output" document. """ File: useGraph.py Author: Derrf Seitz This program exercises graphs. The following files must be in the same folder: abstractcollection.py graph.py """ # # Replace with your name. # Replace any "" comments with your own code statement(s) # to accomplish the specified task. # DO NOT CHANGE ANY OTHER CODE. from graph import LinkedDirectedGraph # Part 1: # Complete the following function: def topologicalSort(graph): <your code> # graph = LinkedDirectedGraph() # The graph represents the following course prerequisites: # A requires nothing # B requires nothing # C requires A # D requires A, B, and C
  • 2. # E requires C # F requires B and D # G requires E and F # H requires C, F, and G # Part 2: # Add the vertices: <your code> # Part 3: # Add the edges: <your code> # print("Graph:") print(graph) print() print("Courses:") # Part 4: # Display each vertex on a separate line: <your code> # print() print("Prerequisites:") # Part 5: # Display each edge on a separate line: <your code> # print() print("One possible order to take the courses:") # Part 6: # Display the courses in prerequisite (topological) order:
  • 3. <your code> # print() """ File: graph.py Author: Ken Lambert, copyright 2015, 2020 Used by permission. Adds the in, +, ==, and clone operations to support graph-specific behavior. """ from abstractcollection import AbstractCollection class LinkedEdge(object): # An edge has a source vertex, a destination vertex, # a weight, and a mark attribute. # Constructor def __init__(self, fromVertex, toVertex, weight = None): self.vertex1 = fromVertex self.vertex2 = toVertex self.weight = weight self.mark = False # Accessor methods def __eq__(self, other): """Two edges are equal if they connect the same vertices.""" if self is other: return True if type(self) != type(other): return False return self.vertex1 == other.vertex1 and self.vertex2 == other.vertex2 def __hash__(self): # Derrf Seitz 11/16/2020 """Hash method for an edge.""" return hash(self.vertex1.label + self.vertex2.label) def __str__(self): """Returns the string representation of the edge.""" return str(self.vertex1) + ">" + str(self.vertex2) + ":" + str(self.weight)
  • 4. def getFromVertex(self): # Derrf Seitz 12/17/2015 """Returns the edge's origin vertex.""" return self.vertex1 def getOtherVertex(self, thisVertex): """Returns the vertex opposite thisVertex.""" if thisVertex == None or thisVertex == self.vertex2: return self.vertex1 else: return self.vertex2 def getToVertex(self): """Returns the edge's destination vertex.""" return self.vertex2 def getWeight(self): """Returns the edge's weight.""" return self.weight def isMarked(self): """Returns True if the edge is marked or False otherwise.""" return self.mark # Mutator methods def clearMark(self): """Clears the mark on the edge.""" self.mark = False def setMark(self): """Sets the mark on the edge.""" self.mark = True def setWeight(self, weight): """Sets the weight on the edge to weight.""" self.weight = weight class LinkedVertex(object): # A vertex has a label, a list of incident edges, # and a mark attribute. # Constructor def __init__(self, label): self.label = label
  • 5. self.edgeList = list() self.mark = False # Accessor methods def __eq__(self, other): """Two vertices are equal if they have the same labels.""" if self is other: return True if type(self) != type(other): return False return self.getLabel() == other.getLabel() def __hash__(self): # Derrf Seitz 12/16/2015 """Hash method for a vertex.""" return hash(self.label) def __str__(self): """Returns the string representation of the vertex.""" return str(self.label) def getEdgeTo(self, toVertex): """Returns the connecting edge if it exists, or None otherwise.""" edge = LinkedEdge(self, toVertex) try: return self.edgeList[self.edgeList.index(edge)] except: return None def getLabel(self): """Returns the label of the vertex.""" return self.label def incidentEdges(self): """Returns the incident edges of this vertex.""" return iter(self.edgeList) def isMarked(self): """Returns True if the vertex is marked or False otherwise.""" return self.mark def neighboringVertices(self): """Returns the neighboring vertices of this vertex.""" vertices = list()
  • 6. for edge in self.edgeList: vertices.append(edge.getOtherVertex(self)) return iter(vertices) # Mutator methods def addEdgeTo(self, toVertex, weight): """Connects the vertices with an edge.""" edge = LinkedEdge(self, toVertex, weight) self.edgeList.append(edge) def clearMark(self): """Clears the mark on the vertex.""" self.mark = False; def removeEdgeTo(self, toVertex): """Returns True if the edge exists and is removed, or False otherwise.""" edge = LinkedEdge(self, toVertex) if edge in self.edgeList: self.edgeList.remove(edge) return True else: return False def setLabel(self, label, g): """Sets the vertex's label to label.""" g.vertices.pop(self.label, None) g.vertices[label] = self self.label = label def setMark(self): """Sets the mark on the vertex.""" self.mark = True class LinkedDirectedGraph(AbstractCollection): # A graph has a count of vertices, a count of edges, # and a dictionary of label/vertex pairs. # Class variables INTERFACE = "GraphInterface" # Constructor def __init__(self, sourceCollection = None): self.edgeCount = 0 self.vertices = dict() # Dictionary of vertices
  • 7. AbstractCollection.__init__(self, sourceCollection) # Accessor methods def __contains__(self, item): """Returns True if item is a label in a vertex, or False otherwise.""" for vertex in self: if vertex.getLabel() == item: return True return False def __eq__(self, other): """Returns True if self and other are identical, or True if self and other are of the same type, have the same number of vertices, and these vertices are connected in the same manner (including same labels and edge weights).""" # Check simple criteria first if self is other: return True if type(self) != type(other): return False if len(self) != len(other): return False for vertex in self: # All vertex labels must match if not vertex.getLabel() in other: print("Mismatched vertices") return False # Vertices with the same labels must have the same # incident edges otherVertex = other.getVertex(vertex.getLabel()) selfEdges = list(vertex.incidentEdges()) otherEdges = list(otherVertex.incidentEdges()) if len(selfEdges) != len(otherEdges): return False for edge in selfEdges: found = False for otherEdge in otherEdges: if edge == otherEdge and edge.getWeight() == otherEdge.getWeight(): found = True break if not found: return False return True def __iter__(self):
  • 8. """Supports iteration over a view of self (the vertices).""" return self.getVertices() def __str__(self): """Returns the string representation of the graph.""" result = str(len(self)) + " Vertices: " for vertex in self.vertices: result += " " + str(vertex) result += "n"; result += str(self.sizeEdges()) + " Edges: " for edge in self.edges(): result += " " + str(edge) return result def containsEdge(self, fromLabel, toLabel): """Returns True if an edge connects the vertices, or False otherwise.""" return self.getEdge(fromLabel, toLabel) != None def containsVertex (self, label): return label in self.vertices def clone(self): """Returns an exact copy of self, including vertex labels, edges connecting vertices, and edge weights.""" newGraph = type(self)(map(lambda vertex: vertex.getLabel(), self)) for vertex in self: for neighbor in vertex.neighboringVertices(): edge = vertex.getEdgeTo(neighbor) newGraph.addEdge(vertex.getLabel(), neighbor.getLabel(), edge.getWeight()) return newGraph def edges(self): """Supports iteration over the edges in the graph.""" result = set() for vertex in self.getVertices(): edges = vertex.incidentEdges() result = result.union(set(edges)) return iter(result) def getEdge(self, fromLabel, toLabel): """Returns the edge connecting the two vertices, or None if no edge exists. Precondition: vertices with fromLabel and toLabel must
  • 9. already be in the graph. Raises: AttibuteError if the vertices are not already in the graph.""" fromVertex = self.getVertex(fromLabel) toVertex = self.getVertex(toLabel) return fromVertex.getEdgeTo(toVertex) def getVertex(self, label): """Precondition: a vertex with label must already be in the graph. Raises: AttibuteError if a vertex with label is not already in the graph.""" if not self.containsVertex(label): raise AttributeError("Label " + str(label) + " not in graph.""") return self.vertices[label] def getVertices(self): """Supports iteration over the vertices in the graph.""" return iter(self.vertices.values()) def incidentEdges(self, label): """Supports iteration over the incident edges of the given verrtex. Precondition: a vertex with label must already be in the graph. Raises: AttibuteError if a vertex with label is not already in the graph.""" return self.getVertex(label).incidentEdges() def neighboringVertices(self, label): """Supports iteration over the neighboring vertices of the given verrtex. Precondition: a vertex with label must already be in the graph. Raises: AttibuteError if a vertex with label is not already in the graph.""" return self.getVertex(label).neighboringVertices() def sizeEdges(self): """Returns the number of edges.""" return self.edgeCount def sizeVertices(self): """Returns the number of vertices.""" return len(self) # Mutator methods def __add__(self, other): """Returns a new collection consisting of the items in self and other. This will be a graph with the contents of the operand graphs as separate components. Precondition: the labels in the two graph operands are disjoint.
  • 10. Raises: AttributeError if the labels in the two operand graphs are not disjoint.""" newGraph = self.clone() for vertex in other: newGraph.add(vertex.getLabel()) for vertex in other: for neighbor in vertex.neighboringVertices(): edge = vertex.getEdgeTo(neighbor) newGraph.addEdge(vertex.getLabel(), neighbor.getLabel(), edge.getWeight()) return newGraph def add(self, label): """For compatibility with other collections.""" self.addVertex(label) def addEdge(self, fromLabel, toLabel, weight): """Connects the vertices with an edge with the given weight. Preconditions: vertices with fromLabel and toLabel must already be in the graph. The vertices must not already be connected by an edge. Raises: AttibuteError if the vertices are not already in the graph or they are already connected.""" fromVertex = self.getVertex(fromLabel) toVertex = self.getVertex(toLabel) if self.getEdge(fromLabel, toLabel): raise AttributeError("An edge already connects " + str(fromLabel) + " and " + str(toLabel)) fromVertex.addEdgeTo(toVertex, weight) self.edgeCount += 1 def addVertex(self, label): """Precondition: a vertex with label must not already be in the graph. Raises: AttibuteError if a vertex with label is already in the graph.""" if self.containsVertex(label): raise AttributeError("Label " + str(label) + " already in graph.""") self.vertices[label] = LinkedVertex(label) self.size += 1 def clear(self): """Clears the graph.""" self.size = 0
  • 11. self.edgeCount = 0 self.vertices = dict() def clearEdgeMarks(self): """Clears all the edge marks.""" for edge in self.edges(): edge.clearMark() def clearVertexMarks(self): """Clears all the vertex marks.""" for vertex in self.getVertices(): vertex.clearMark() def removeEdge (self, fromLabel, toLabel): """Returns True if the edge was removed, or False otherwise. Precondition: vertices with fromLabel and toLabel must already be in the graph. Raises: AttibuteError if the vertices are not already in the graph.""" fromVertex = self.getVertex(fromLabel) toVertex = self.getVertex(toLabel) edgeRemovedFlg = fromVertex.removeEdgeTo(toVertex) if edgeRemovedFlg: self.edgeCount -= 1 return edgeRemovedFlg def removeVertex(self, label): """Returns True if the vertex was removed, or False otherwise.""" removedVertex = self.vertices.pop(label, None) if removedVertex is None: return False # Examine all other vertices to remove edges # directed at the removed vertex for vertex in self.getVertices(): if vertex.removeEdgeTo(removedVertex): self.edgeCount -= 1 # Examine all edges from the removed vertex to others for edge in removedVertex.incidentEdges(): self.edgeCount -= 1 self.size -= 1 return True