[Zope-CVS] CVS: Packages/pypes/pypes - exceptions.py:1.2
graph.py:1.5 interfaces.py:1.3
Casey Duncan
casey at zope.com
Sun Aug 10 23:32:51 EDT 2003
Update of /cvs-repository/Packages/pypes/pypes
In directory cvs.zope.org:/tmp/cvs-serv5187
Modified Files:
exceptions.py graph.py interfaces.py
Log Message:
Implement topological sorting of graph nodes
=== Packages/pypes/pypes/exceptions.py 1.1.1.1 => 1.2 ===
--- Packages/pypes/pypes/exceptions.py:1.1.1.1 Mon Aug 4 00:46:02 2003
+++ Packages/pypes/pypes/exceptions.py Sun Aug 10 22:32:15 2003
@@ -43,3 +43,6 @@
class GraphValueError(PypesError):
"""Value could not be retreived from graph"""
+
+class GraphCycleError(PypesError):
+ """Cycle detected during operation for acyclic graph"""
=== Packages/pypes/pypes/graph.py 1.4 => 1.5 ===
--- Packages/pypes/pypes/graph.py:1.4 Sat Aug 9 00:06:59 2003
+++ Packages/pypes/pypes/graph.py Sun Aug 10 22:32:15 2003
@@ -27,6 +27,7 @@
from pypes.interfaces import IGraph, IGraphEdges, IGraphNodes
from pypes.exceptions\
import IdentityError, IdentityKeyError, GraphLookupError, GraphValueError
+from pypes.exceptions import GraphCycleError
_marker = object()
@@ -258,11 +259,11 @@
if path[-1] is target:
return path
- def _dijkstraSearch(self, source, target):
- """Return the shortest list of nodes connecting source to target
- with the smallest cumulative distance derived from the edge values
- using Dijkstra's algorithm. Note, this does not work correctly if
- edges have negative values
+ def _dijkstraSearch(self, source, target):
+ """Return the list of nodes connecting source to target with the
+ smallest cumulative distance derived from the edge values using
+ Dijkstra's algorithm. Note, this does not work correctly if edges have
+ negative values
"""
nodes = PQueue()
nodes.insert(source, None)
@@ -270,9 +271,7 @@
while nodes:
n, nd = nodes.popMin()
referers, targets = self._nodes[n]
- if targets is None:
- continue
- else:
+ if targets is not None:
if not isinstance(targets, self._nodeSetFactory):
targets = (targets,)
for t in targets:
@@ -368,7 +367,42 @@
return iter(self._nodes.keys())
def iterTopological(self):
- raise NotImplementedError
+ UNDISCOVERED = None
+ DISCOVERED = 1
+ EXPLORED = 2
+ status = {}
+ nodes = []
+ for n in self._nodes.keys():
+ if n not in status:
+ nodes.append(n)
+ while nodes:
+ dn = nodes[-1]
+ if status.get(dn) == EXPLORED:
+ nodes.pop()
+ else:
+ referers, targets = self._nodes[dn]
+ is_explored = True
+ if targets is not None:
+ status[dn] = DISCOVERED
+ if isinstance(targets, self._nodeSetFactory):
+ for t in targets:
+ ts = status.get(t)
+ if ts == UNDISCOVERED:
+ is_explored = False
+ nodes.append(t)
+ elif ts == DISCOVERED:
+ raise GraphCycleError, t
+ else:
+ ts = status.get(targets)
+ if ts == UNDISCOVERED:
+ is_explored = False
+ nodes.append(targets)
+ elif ts == DISCOVERED:
+ raise GraphCycleError, targets
+ if is_explored:
+ status[dn] = EXPLORED
+ nodes.pop()
+ yield dn
def degree(self, node):
try:
=== Packages/pypes/pypes/interfaces.py 1.2 => 1.3 ===
--- Packages/pypes/pypes/interfaces.py:1.2 Fri Aug 8 00:57:49 2003
+++ Packages/pypes/pypes/interfaces.py Sun Aug 10 22:32:15 2003
@@ -270,7 +270,7 @@
def iterTopological():
"""Return an iterator of the nodes in topologically sorted order.
The graph must be directed and acyclic. If a cycle is encountered
- or the graph is not directed raise GraphSortError.
+ during iteration, raise GraphCycleError.
"""
def degree(node):
More information about the Zope-CVS
mailing list