File Coverage

blib/lib/Graph/MoreUtils/Line.pm
Criterion Covered Total %
statement 45 46 97.8
branch 12 14 85.7
condition 4 7 57.1
subroutine 8 8 100.0
pod 0 1 0.0
total 69 76 90.7


line stmt bran cond sub pod time code
1             package Graph::MoreUtils::Line;
2              
3             # ABSTRACT: Generate line graphs
4             our $VERSION = '0.3.0'; # VERSION
5              
6 9     9   132996 use strict;
  9         457  
  9         500  
7 9     9   57 use warnings;
  9         24  
  9         2686  
8              
9 9     9   5333 use Algorithm::Combinatorics qw( combinations );
  9         47690  
  9         744  
10 9     9   7061 use Graph;
  9         506888  
  9         522  
11 9     9   5725 use Graph::MoreUtils::Line::SelfLoopVertex;
  9         38  
  9         357  
12 9     9   4337 use Graph::Undirected;
  9         3414  
  9         338  
13 9     9   62 use Scalar::Util qw( blessed );
  9         18  
  9         5115  
14              
15             sub line
16             {
17 10     10 0 31 my( $graph, $options ) = @_;
18              
19 10 50 33     104 if( !blessed $graph || !$graph->isa( Graph:: ) ) {
20 0         0 die 'only Graph and its derivatives are accepted' . "\n";
21             }
22              
23 10 100       37 $options = {} unless $options;
24              
25 10         57 my $line_graph = Graph->new( directed => $graph->is_directed,
26             refvertexed => 1 );
27              
28             # Add the edges as vertices to the edge graph
29 10 100       2095 if( $graph->is_multiedged ) {
30 4         44 for my $unique_edge ($graph->unique_edges) {
31 4         722 for my $edge ($graph->get_multiedge_ids( @$unique_edge )) {
32 9   50     2607 my $edge_vertex = $graph->get_edge_attributes_by_id( @$unique_edge, $edge ) || {};
33 9         2389 $line_graph->add_path( $unique_edge->[0], $edge_vertex, $unique_edge->[1] );
34             }
35             }
36             } else {
37 6         55 for my $edge ($graph->edges) {
38 22   100     5299 my $edge_vertex = $graph->get_edge_attributes( @$edge ) || {};
39 22         3895 $line_graph->add_path( $edge->[0], $edge_vertex, $edge->[1] );
40             }
41             }
42              
43             # Interconnect edge vertices which share the original vertex
44 10         3422 for my $vertex ($graph->vertices) {
45 26 100       8179 if( $graph->is_directed ) {
46             # TODO: Check for self-loops
47 6         31 for my $in ($line_graph->predecessors( $vertex )) {
48 12         2022 for my $out ($line_graph->successors( $vertex )) {
49 24         4389 $line_graph->set_edge_attribute( $in,
50             $out,
51             'original_vertex',
52             $vertex );
53             }
54             }
55             } else {
56 20 50       191 next unless $line_graph->degree( $vertex );
57 20 100       10157 if( $line_graph->degree( $vertex ) > 1 ) {
    100          
58 13         6771 for my $edge (combinations( [ $line_graph->neighbours( $vertex ) ], 2 )) {
59 17         5660 $line_graph->set_edge_attribute( @$edge, 'original_vertex', $vertex );
60             }
61             } elsif( $options->{loop_end_vertices} ) {
62 2         1541 $line_graph->set_edge_attribute( $line_graph->neighbours( $vertex ),
63             Graph::MoreUtils::Line::SelfLoopVertex->new,
64             'original_vertex',
65             $vertex );
66             }
67             }
68             }
69              
70 10         4383 $line_graph->delete_vertices( $graph->vertices );
71              
72 10         8852 return $line_graph;
73             }
74              
75             1;