File: Smooth.pm

package info (click to toggle)
libgraph-moreutils-perl 0.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 152 kB
  • sloc: perl: 385; makefile: 2
file content (58 lines) | stat: -rw-r--r-- 2,063 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package Graph::MoreUtils::Smooth;

# ABSTRACT: Generate smoothed graphs
our $VERSION = '0.3.0'; # VERSION

use strict;
use warnings;

use Graph::MoreUtils::Smooth::Intermediate;
use Graph::Undirected;
use Scalar::Util qw( blessed );

sub smooth
{
    my( $graph ) = @_;

    if( !blessed $graph || !$graph->isa( Graph::Undirected:: ) ) {
        die 'only Graph::Undirected and its derivatives are accepted' . "\n";
    }

    for ($graph->vertices) {
        next unless $graph->degree( $_ ) == 2;
        my( $a, $b ) = sort $graph->neighbours( $_ );

        # do not reduce cycles of three vertices:
        next if $graph->has_edge( $a, $b );

        my $intermediate;
        if( $graph->has_edge_attribute( $a, $_, 'intermediate' ) &&
            $graph->has_edge_attribute( $b, $_, 'intermediate' ) ) {
            $intermediate = Graph::MoreUtils::Smooth::Intermediate->new(
                $_ lt $a
                    ? $graph->get_edge_attribute( $a, $_, 'intermediate' )->reverse
                    : $graph->get_edge_attribute( $a, $_, 'intermediate' ),
                $_,
                $_ gt $b
                    ? $graph->get_edge_attribute( $b, $_, 'intermediate' )->reverse
                    : $graph->get_edge_attribute( $b, $_, 'intermediate' ) );
        } elsif( $graph->has_edge_attribute( $a, $_, 'intermediate' ) ) {
            $intermediate = $graph->get_edge_attribute( $a, $_, 'intermediate' );
            $intermediate->reverse if $a gt $_; # getting natural order
            push @$intermediate, $_;
        } elsif( $graph->has_edge_attribute( $b, $_, 'intermediate' ) ) {
            $intermediate = $graph->get_edge_attribute( $b, $_, 'intermediate' );
            $intermediate->reverse if $_ gt $b; # getting natural order
            unshift @$intermediate, $_;
        } else {
            $intermediate = Graph::MoreUtils::Smooth::Intermediate->new( $_ );
        }

        $graph->delete_vertex( $_ );
        $graph->set_edge_attribute( $a, $b, 'intermediate', $intermediate );
    }

    return $graph;
}

1;