|
Revision 281, 1.8 kB
(checked in by simon, 4 years ago)
|
|
Functions for dealing with graphs.
|
-
Property svn:mime-type set to
text/python-source
-
Property svn:eol-style set to
native
|
| Line | |
|---|
| 1 | import networkx |
|---|
| 2 | import networkx.search |
|---|
| 3 | |
|---|
| 4 | class CycleFinder(object): |
|---|
| 5 | def find_cycles(self,oG): |
|---|
| 6 | pass |
|---|
| 7 | |
|---|
| 8 | @classmethod |
|---|
| 9 | def count_cycles(cls,oG): |
|---|
| 10 | """Return the number of cycles in graph oG.""" |
|---|
| 11 | aBackEdges = cls._find_back_edges(oG) |
|---|
| 12 | |
|---|
| 13 | oCopyOfG = oG.copy() |
|---|
| 14 | |
|---|
| 15 | iCycles = 0 |
|---|
| 16 | for tEdge in aBackEdges: |
|---|
| 17 | oCopyOfG.delete_edge(tEdge) |
|---|
| 18 | iCycles += cls._count_cycles_for_back_edge(tEdge,oCopyOfG) |
|---|
| 19 | |
|---|
| 20 | return iCycles |
|---|
| 21 | |
|---|
| 22 | @staticmethod |
|---|
| 23 | def _find_back_edges(oG): |
|---|
| 24 | if not oG.order(): |
|---|
| 25 | return {} |
|---|
| 26 | |
|---|
| 27 | oN = oG.nodes()[0] |
|---|
| 28 | |
|---|
| 29 | aBackEdges = set() |
|---|
| 30 | aNodeStack = [oN] |
|---|
| 31 | dParents = { oN: None } |
|---|
| 32 | aPath = set() |
|---|
| 33 | |
|---|
| 34 | while aNodeStack: |
|---|
| 35 | oN = aNodeStack.pop() |
|---|
| 36 | |
|---|
| 37 | for oChild in oG[oN]: |
|---|
| 38 | if oChild is dParents[oN]: |
|---|
| 39 | continue |
|---|
| 40 | |
|---|
| 41 | if oChild in dParents: |
|---|
| 42 | if (oChild,oN) not in aBackEdges: |
|---|
| 43 | aBackEdges.add((oN,oChild)) |
|---|
| 44 | else: |
|---|
| 45 | aNodeStack.append(oChild) |
|---|
| 46 | dParents[oChild] = oN |
|---|
| 47 | |
|---|
| 48 | return aBackEdges |
|---|
| 49 | |
|---|
| 50 | @staticmethod |
|---|
| 51 | def _count_cycles_for_back_edge(tEdge,oG): |
|---|
| 52 | oFirst = tEdge[0] |
|---|
| 53 | oSecond = tEdge[1] |
|---|
| 54 | |
|---|
| 55 | iCycles = 0 |
|---|
| 56 | aNodeStack = [(oSecond, set())] |
|---|
| 57 | |
|---|
| 58 | while aNodeStack: |
|---|
| 59 | oN, aPath = aNodeStack.pop() |
|---|
| 60 | |
|---|
| 61 | for oChild in oG[oN]: |
|---|
| 62 | if oChild in aPath: |
|---|
| 63 | continue |
|---|
| 64 | |
|---|
| 65 | if oChild is oFirst: |
|---|
| 66 | iCycles += 1 |
|---|
| 67 | continue |
|---|
| 68 | |
|---|
| 69 | aChildPath = aPath.copy() |
|---|
| 70 | aChildPath.add(oN) |
|---|
| 71 | aNodeStack.append((oChild,aChildPath)) |
|---|
| 72 | |
|---|
| 73 | print tEdge, iCycles |
|---|
| 74 | return iCycles |
|---|
| 75 | |
|---|
| 76 | count_cycles = CycleFinder.count_cycles |
|---|