Graph-Fast

 view release on metacpan or  search on metacpan

lib/Graph/Fast.pm  view on Meta::CPAN

	if (!defined($self->{d_from}) or $self->{d_from} ne $from) {
		goto &dijkstra_first;
	} else {
		goto &dijkstra_continue;
	}
}

sub recursive_dijkstra {
	my ($self, $from, $to, $level, $del_to) = @_;
	my @d = ([ $self->dijkstra($from, $to, $del_to) ]);

	if (!defined($d[0]->[0])) {
		return ();
	}

	if ($level > 0) {
		foreach (0..(@{$d[0]}-1)) {
			# from copies of the graph, remove one edge from the result path,
			# and continue finding paths on that tree.
			my $ffffuuuu = $self->{_queue_maker};
			$self->{_queue_maker} = "omg";
			my $g2 = dclone($self);
			$g2->{_queue_maker} = $self->{_queue_maker} = $ffffuuuu;

			$g2->del_edge($d[0]->[$_]->{from}, $d[0]->[$_]->{to});
			my @new = $g2->recursive_dijkstra($from, $to, $level - 1, $d[0]->[$_]->{to});

			# add all new paths, unless they are already present in the result set
			foreach my $n (@new) {
				push(@d, $n) unless (grep { $n ~~ $_ } @d);
			}
		}
	}

	@d;
}

sub add_edge {
	my ($self, $from, $to, $weight, $user_data) = @_;
	$self->del_edge($from => $to);

	my $edge = { from => $from, to => $to, weight => $weight, (defined($user_data) ? (user_data => $user_data) : ()) };

	push(@{$self->{edges}}, $edge);
	($self->{vertices}->{$from} // $self->add_vertex($from))->{edges_out}->{$to}   = $edge;
	($self->{vertices}->{$to  } // $self->add_vertex($to  ))->{edges_in }->{$from} = $edge;
}

sub del_edge {
	my ($self, $from, $to) = @_;

	# find the edge. assume it only exists once -> only delete the first.
	# while we're at it, delete the edge from the source vertex...
	my $e = $self->{vertices}->{$from}->{edges_out}->{$to};
	return undef if (!defined($e));
	delete($self->{vertices}->{$from}->{edges_out}->{$to});

	# now search it in the destination vertex' list, delete it there
	# also only delete the first matching one here (though now there
	# shouldn't be any duplicates at all because now we're matching the
	# actual edge, not just its endpoints like above.
	delete($self->{vertices}->{$to}->{edges_in}->{$from});

	# and remove it from the graph's vertex list
	@{$self->{edges}} = grep { $_ != $e } @{$self->{edges}}
}

1;

__END__

=head1 NAME

Graph::Fast - graph data structures and algorithms, just faster.

=head1 SYNOPSIS

 # todo

=head1 DESCRIPTION

Graph::Fast implements a mathematical abstract data structure, called graph,
that models relations between objects with vertices and edges.

=head2 Graph::Fast vs Graph

While L<Graph> is a module with a lot of features, it is not really fast.
Graph::Fast doesn't implement all the features, but it is much faster.
Graph::Fast is for you if you need the most important things done very
fast.

=head1 FUNCTIONS

Available functions are:

=head2 B<new>(I<optional options...>)

Constructs a new Graph::Fast object.

The constructor takes optional parameters as a hash. Currently there are
no options.

=head2 B<count_edges>()

Returns the number of edges in the graph.

=head2 B<count_vertices>()

Returns the number of vertices in the graph.

=head2 B<add_vertex>(I<$name>)

Adds a vertex with the specified name to the graph. Names must be unique.
It is safe to call this with a name that already exists in the graph.

=head2 B<del_vertex>(I<$name>)

Deletes a vertex with the specified name from the graph. All edges that
go from or to the specified edges will be deleted as well. It is safe to
call this with a name that doesn't exist.



( run in 1.260 second using v1.01-cache-2.11-cpan-39bf76dae61 )