graphlib icon indicating copy to clipboard operation
graphlib copied to clipboard

findCycles only finds longest cycle when there is some overlap

Open graemian opened this issue 8 years ago • 7 comments

Consider this example:

g2 = new graphlib.Graph({directed: true});

g2.setNode("1");
g2.setNode("2");
g2.setNode("3");

g2.setEdge("1", "2");
g2.setEdge("2", "3");
g2.setEdge("3", "1");

graphlib.alg.findCycles(g2);
// [ [ '3', '2', '1' ] ]

g2.setNode("4");

g2.setEdge("3", "4");
g2.setEdge("4", "1");

graphlib.alg.findCycles(g2);
// [ [ '4', '3', '2', '1' ] ]

Surely the cycle [3, 2, 1] should also be found by the last statement?

graemian avatar May 12 '17 12:05 graemian

@graemian was this ever resolved?

temitope avatar May 01 '18 02:05 temitope

@temitope Nope, I don't think so

graemian avatar May 08 '18 13:05 graemian

Another example where it fails:

var g = new Graph();

g.setEdge(1, 2);
g.setEdge(2, 3);
g.setEdge(3, 4);
g.setEdge(3, 1);
g.setEdge(4, 1);
g.setEdge(4, 5);
g.setEdge(5, 3);

alg.findCycles(g);
// [ [ '5', '4', '3', '2', '1' ] ]

The output should have been: [ [ 1, 2, 3,], [1, 2, 3, 4], [3, 4, 5] ]

In fact 5-4-3-2-1 is not even a simple cycle on the graph ( '3' needs to be traversed twice while not being the starting node )

mstou avatar Aug 27 '18 23:08 mstou

Looking at the source code, the findCycles() implementation is the following:

function findCycles(g) {
  return _.filter(tarjan(g), function(cmpt) {
    return cmpt.length > 1 || (cmpt.length === 1 && g.hasEdge(cmpt[0], cmpt[0]));
  });
}

tarjan(g) returns an array with all the strongly connected components of the graph We filter that array ,removing singleton arrays whose nodes have no self edges, and return it. So, the returned array is just the strongly connected components filtered.

This falsely assumes that a strongly connected component contains only one cycle.

Finding all the simple cycles in a graph is a bit more complex, we need to run Johnson's Algorithm I will try to implement it and open a pull request

mstou avatar Aug 27 '18 23:08 mstou

@mstou implementation PR would be greatly appreciated!

kimchirichie avatar Jan 25 '19 21:01 kimchirichie

@mstou would be awesome!

ctfvdheijden avatar Jul 25 '19 18:07 ctfvdheijden

This is a severe bug because "findCycles" simply does not return all cycles and users like me have a hard time to figure out why our projects break! Please fix this and until then, make clear in the wiki that it's only "findSomeCycles" at the moment!

VotingTool avatar Jun 09 '20 19:06 VotingTool