File Coverage

blib/lib/Graph/Line.pm
Criterion Covered Total %
statement 51 51 100.0
branch 12 12 100.0
condition 5 7 71.4
subroutine 7 7 100.0
pod 1 1 100.0
total 76 78 97.4


line stmt bran cond sub pod time code
1             package Graph::Line;
2              
3 6     6   92605 use strict;
  6         43  
  6         163  
4 6     6   27 use warnings;
  6         11  
  6         188  
5              
6 6     6   2712 use parent 'Graph::Undirected';
  6         1796  
  6         28  
7              
8 6     6   182809 use Graph::Line::SelfLoopVertex;
  6         14  
  6         158  
9 6     6   36 use Graph::Undirected;
  6         10  
  6         136  
10 6     6   27 use Scalar::Util qw( blessed );
  6         13  
  6         3060  
11              
12             # ABSTRACT: Generate line graphs
13             our $VERSION = '0.1.0'; # VERSION
14              
15             sub new
16             {
17 9     9 1 62029 my( $class, $graph, $options ) = @_;
18              
19 9 100 66     151 if( !blessed $graph || !$graph->isa( Graph::Undirected:: ) ) {
20 1         15 die 'only Graph::Undirected and its derivatives accepted' . "\n";
21             }
22              
23 8 100       31 $options = {} unless $options;
24              
25             # Collect all edges prior to converting them to vertices:
26 8         20 my @originals;
27             my @new_vertices;
28 8 100       48 if( $graph->is_multiedged ) {
29 4         37 for my $unique_edge ($graph->unique_edges) {
30 4         118 for my $edge ($graph->get_multiedge_ids( @$unique_edge )) {
31 9         1010 push @originals, $unique_edge;
32 9   50     32 push @new_vertices,
33             $graph->get_edge_attributes_by_id( @$unique_edge,
34             $edge ) || {};
35             }
36             }
37             } else {
38             # Have to do this in for cycle to maintain relation between the
39             # parallel arrays:
40 4         42 for my $edge ($graph->edges) {
41 10         863 push @originals, $edge;
42 10   100     70 push @new_vertices,
43             $graph->get_edge_attributes( @$edge ) || {};
44             }
45             }
46              
47             # Collect adjacent edges for every vertice
48 8         913 my $adjacency = {};
49 8         50 for my $i (0..$#originals) {
50 19         26 push @{$adjacency->{$originals[$i]->[0]}}, $new_vertices[$i];
  19         44  
51              
52             # Self-loops have to be detected and not added once again
53 19 100       47 next if $originals[$i]->[0] eq $originals[$i]->[1];
54              
55 16         21 push @{$adjacency->{$originals[$i]->[1]}}, $new_vertices[$i];
  16         37  
56             }
57              
58             # Create the line graph
59 8         40 my $line_graph = Graph::Undirected->new;
60 8         1667 $line_graph->add_vertices( @new_vertices );
61 8         406 for my $vertex (sort keys %$adjacency) {
62 20         2506 for my $i (0..$#{$adjacency->{$vertex}}-1) {
  20         58  
63 15         501 for my $j ($i+1..$#{$adjacency->{$vertex}}) {
  15         34  
64             $line_graph->set_edge_attribute( $adjacency->{$vertex}[$i],
65 17         590 $adjacency->{$vertex}[$j],
66             'original_vertex',
67             $vertex );
68             }
69             }
70             }
71              
72             # Add self-loops for end vertices if requested
73 8 100       813 if( $options->{loop_end_vertices} ) {
74 2         8 for my $vertex ($graph->vertices) {
75 5 100       832 next if $graph->degree( $vertex ) != 1;
76             # Adjacency matrix will only have one item
77 2         500 $line_graph->set_edge_attribute( $adjacency->{$vertex}[0],
78             Graph::Line::SelfLoopVertex->new,
79             'original_vertex',
80             $vertex );
81             }
82             }
83              
84 8         525 return bless $line_graph, $class;
85             }
86              
87             1;
88              
89             __END__