Finding cycles in weighted directed multi graph (Gephi, Jython, Python)

1k views Asked by At

I have a directed, multi, weighted graph. I want to find cycles where a -> b -> c -> a

A sample of my graph. I hope it it clear:

v1 -> v2
v2 -> v3
v3 -> v1
v1 -> v4
v2 -> v5

How to iterate only nodes that are targets? This is my shor

results = []

for n in g.nodes: # iterates all nodes
    x = n #marks the first node
    for n1 in n.neighbors: #iterates neighbors, but this part should include only neighbors that are targets.
        y = n1 # marks second node
        for n2 in n.neighbors: #same as above, should select only target neighbors.
            if n2 == x:
                print "FOUND"

I believe the decision should come up by using Gython grammar, excerpt from Jython tutorial:

v1 -> v2 (or v2 <- v1): selects the directed edge from node v1 to node v2.

My end result should be:

results = [[v1,v2,v3]]
1

There are 1 answers

2
Hyperboreus On

Sure some graph lib will bring this functionality. If you want to do it by hand, maybe this (quick and dirty, Dijkstra would kill me) snippet might give you some hints:

(I added another vertex from v5 to v2 in order to get more than one cycle)

#! /usr/bin/python3

class Node:
    def __init__ (self, name):
        self.name = name
        self.neighbours = []

    def connect (self, other):
        self.neighbours.append (other)

    def paths (self, path = None):
        path = path [:] if path else []
        if self in path: return [path + [self] ]
        path.append (self)
        paths = []
        for neighbour in self.neighbours:
            paths.extend (neighbour.paths (path) )
        return paths if paths else [path]

    def cycles (self):
            paths = self.paths ()
            return [path for path in paths if len (path) > 1 and path [-1] == self]

    def __repr__ (self):
        return self.name

nodes = [Node ('v1'), Node ('v2'), Node ('v3'), Node ('v4'), Node ('v5') ]
nodes [0].connect (nodes [1] )
nodes [1].connect (nodes [2] )
nodes [2].connect (nodes [0] )
nodes [0].connect (nodes [3] )
nodes [0].connect (nodes [4] )
nodes [4].connect (nodes [1] )

for node in nodes:
    print (node, node.cycles () )