use Test::More tests => 57; use Graph; use Graph::Undirected; my $g0 = Graph->new; $g0->add_cycle(qw(a b)); $g0->add_edge(qw(b c)); my @c0 = $g0->strongly_connected_components; is(@c0, 2); @c0 = sort { @$a <=> @$b } @c0; is("@{$c0[0]}", 'c'); is("@{[sort @{$c0[1]}]}", 'a b'); is($g0->strongly_connected_graph, "a+b-c"); ok(!$g0->is_strongly_connected); my $g1 = Graph->new; $g1->add_path(qw(f f b a c b)); $g1->add_path(qw(c e d e g h g)); $g1->add_path(qw(f d)); my @c1 = $g1->strongly_connected_components; is(@c1, 4); @c1 = sort { @$a <=> @$b } @c1; is("@{[sort @{$c1[0]}]}", 'f'); is("@{[sort @{$c1[1]}]}", 'd e'); is("@{[sort @{$c1[2]}]}", 'g h'); is("@{[sort @{$c1[3]}]}", 'a b c'); my $g1s = $g1->strongly_connected_graph; is($g1s, "a+b+c-d+e,d+e-g+h,f-a+b+c,f-d+e"); is("@{[sort @{$g1s->get_vertex_attribute('a+b+c', 'subvertices')}]}", "a b c"); is("@{[sort @{$g1s->get_vertex_attribute('d+e', 'subvertices')}]}", "d e"); is("@{[sort @{$g1s->get_vertex_attribute('f', 'subvertices')}]}", "f"); is("@{[sort @{$g1s->get_vertex_attribute('g+h', 'subvertices')}]}", "g h"); is($g1s->get_vertex_attribute('h+g', 'subvertices'), undef); ok(!$g1->is_strongly_connected); my $g2 = Graph->new; $g2->add_cycle(qw(a b c)); $g2->add_cycle(qw(a d e)); my @c2 = $g2->strongly_connected_components; is(@c2, 1); @c2 = sort { @$a <=> @$b } @c2; is("@{[sort @{$c2[0]}]}", 'a b c d e'); is($g2->strongly_connected_graph, "a+b+c+d+e"); ok($g2->is_strongly_connected); my $g3 = Graph->new; $g3->add_path(qw(a b c)); $g3->add_vertices(qw(d e f)); my @c3 = $g3->strongly_connected_components; is(@c3, 6); @c3 = sort { @$a <=> @$b || "@$a" cmp "@$b" } @c3; is("@{[sort @{$c3[0]}]}", 'a'); is("@{[sort @{$c3[1]}]}", 'b'); is("@{[sort @{$c3[2]}]}", 'c'); is("@{[sort @{$c3[3]}]}", 'd'); is("@{[sort @{$c3[4]}]}", 'e'); is("@{[sort @{$c3[5]}]}", 'f'); is($g3->strongly_connected_graph, "a-b,b-c,d,e,f"); ok(!$g3->is_strongly_connected); $g3->add_cycle('d', 'a'); $g3->add_cycle('e', 'f'); is($g3->strongly_connected_graph(hypervertex => sub { my @v = sort @{ $_[0] }; "(" . join(",", @v) . ")" } ), "(a,d)-(b),(b)-(c),(e,f)"); is($g3->strongly_connected_graph(super_component => sub { my @v = sort @_; "(" . join("|", @v) . ")" } ), "(a|d)-(b),(b)-(c),(e|f)"); eval '$g3->strongly_connected_graph(foobar => 1)'; like($@, qr/Graph::strongly_connected_graph: Unknown option: 'foobar' /); # Example from Sedgewick Algorithms in C Third Edition 19.1 Figure 19.8 (p 150) my $g4 = Graph->new; $g4->add_edges([ 0, 1], [ 0, 5], [0, 6]); $g4->add_edges([ 2, 0], [ 2, 3]); $g4->add_edges([ 3, 2], [ 3, 5]); $g4->add_edges([ 4, 2], [ 4, 3], [4, 11]); $g4->add_edges([ 5, 4]); $g4->add_edges([ 6, 4], [ 6, 9]); $g4->add_edges([ 7, 6], [ 7, 8]); $g4->add_edges([ 8, 7], [ 8, 9]); $g4->add_edges([ 9, 10], [ 9, 11]); $g4->add_edges([10, 12]); $g4->add_edges([11, 12]); $g4->add_edges([12, 9]); my @g4s = sort { $a->[0] <=> $b->[0] } map { [sort { $a <=> $b} @$_] } $g4->strongly_connected_components; is(@g4s, 4); is("@{$g4s[0]}", "0 2 3 4 5 6"); is("@{$g4s[1]}", "1"); is("@{$g4s[2]}", "7 8"); is("@{$g4s[3]}", "9 10 11 12"); ok( $g4->same_strongly_connected_components('0', '2')); ok( $g4->same_strongly_connected_components('0', '6')); ok(!$g4->same_strongly_connected_components('0', '1')); ok( $g4->same_strongly_connected_components('7', '8')); ok( $g4->same_strongly_connected_components('9', '10')); ok( $g4->same_strongly_connected_components('9', '12')); ok(!$g4->same_strongly_connected_components('0', '7')); ok(!$g4->same_strongly_connected_components('0', '9')); is( $g4->strongly_connected_component_by_vertex('0'), $g4->strongly_connected_component_by_vertex('2')); isnt($g4->strongly_connected_component_by_vertex('0'), $g4->strongly_connected_component_by_vertex('1')); my @s = $g4->strongly_connected_components(); is( "@{[ sort $g4->strongly_connected_component_by_index(0) ]}", "@{[ sort @{ $s[0] } ]}" ); is( "@{[ sort $g4->strongly_connected_component_by_index(1) ]}", "@{[ sort @{ $s[1] } ]}" ); is( "@{[ sort $g4->strongly_connected_component_by_index(2) ]}", "@{[ sort @{ $s[2] } ]}" ); is( "@{[ sort $g4->strongly_connected_component_by_index(3) ]}", "@{[ sort @{ $s[3] } ]}" ); is( $g4->strongly_connected_component_by_index(4), undef ); my $g5 = Graph::Undirected->new; eval '$g5->strongly_connected_components'; like($@, qr/Graph::strongly_connected_components: expected directed graph, got undirected/); eval '$g5->strongly_connected_component_by_vertex'; like($@, qr/Graph::strongly_connected_component_by_vertex: expected directed graph, got undirected/); eval '$g5->strongly_connected_component_by_index'; like($@, qr/Graph::strongly_connected_component_by_index: expected directed graph, got undirected/); { # http://rt.cpan.org/NoAuth/Bug.html?id=1193 use Graph::Directed; $graph = new Graph::Directed; $graph->add_vertex("a"); $graph->add_vertex("b"); $graph->add_vertex("c"); $graph->add_edge("a","c"); $graph->add_edge("b","c"); $graph->add_edge("c","a"); @cc = $graph->strongly_connected_components; is(@cc, 2); }