
Originally Posted by
Failure
The existence of such a numbering scheme for a given database can easily be checked by topologically sorting the database. I'm not sure how one would detect "all" cycles in such a database doing a topological sort, however - I would have to actually code it...
Coding it is not really as bad as it seems, if we just reuse what we've already got. We can use the depth-first search to do the assigment of level numbers like this, I think:
Code:
def renumberAssembly(assembly, stack):
if assembly.marked:
return [getCycle(assembly, stack)]
cyclesFound = []
newLevel = -1
assembly.marked = True # assembly is on the stack
stack.append(assembly) # should be stack.push(assembly), but it's Python...
for component in assembly.components:
if not component.visited:
cyclesFound += renumberAssembly(component, stack)
newLevel = max(newLevel, component.level)
stack.pop()
assembly.marked = False # assembly is no longer on the stack
assembly.visited = True # depth-first search through assembly is complete
assembly.level = newLevel + 1
return cyclesFound
def renumberDb(db):
cyclesFound = []
for assembly in db:
if not assembly.visited:
cyclesFound += renumberAssembly(assembly, [])
for assembly in db:
assembly.visited = False
return cyclesFound Of course, if cycles have been found, the level-numbering of assemblies does not satisfy the condition that guarantees cycle-freeness of the database.
This version does not just print out the cycles but returns a list of cycles: because I always find functions that just dump out information to the console rather dubious in the first place. That's not what one wants to do anyway.
Warning: Version 5 attached is not really throughly tested. I just wanted to show how easy it is (or, rather, seems to me at the moment) to modify the existing version 4 to incorporate the assignment of level-numbers.
The advantage of having level numbers assigned is that in the case of the critical update operation #3 we can avoid actually invoking renumberAssembly(assembly, []) if the level of the assembly about to be modified is already greater than all the levels of its components, including the new ones.