annotate variant_effect_predictor/Bio/Coordinate/Graph.pm @ 2:a5976b2dce6f

changing defualt values for ensembl database
author mahtabm
date Thu, 11 Apr 2013 17:15:42 +1000
parents 1f6dce3d34e0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
1 # $Id: Graph.pm,v 1.2.2.2 2003/09/08 12:16:18 heikki Exp $
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
2 #
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
3 # bioperl module for Bio::Coordinate::Graph
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
4 #
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
5 # Cared for by Heikki Lehvaslaiho <heikki@ebi.ac.uk>
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
6 #
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
7 # Copyright Heikki Lehvaslaiho
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
8 #
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
9 # You may distribute this module under the same terms as perl itself
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
10
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
11 # POD documentation - main docs before the code
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
12
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
13 =head1 NAME
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
14
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
15 Bio::Coordinate::Graph - Finds shortest path between nodes in a graph
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
16
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
17 =head1 SYNOPSIS
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
18
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
19 # get a hash of hashes representing the graph. E.g.:
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
20 my $hash= {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
21 '1' => {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
22 '2' => 1
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
23 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
24 '2' => {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
25 '4' => 1,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
26 '3' => 1
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
27 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
28 '3' => undef,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
29 '4' => {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
30 '5' => 1
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
31 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
32 '5' => undef
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
33 };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
34
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
35 # create the object;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
36 my $graph = Bio::Coordinate::Graph->new(-graph => $hash);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
37
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
38 # find the shortest path between two nodes
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
39 my $a = 1;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
40 my $b = 6;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
41 my @path = $graph->shortest_paths($a);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
42 print join (", ", @path), "\n";
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
43
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
44
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
45 =head1 DESCRIPTION
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
46
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
47 This class calculates the shortest path between input and output
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
48 coordinate systems in a graph that defines the relationships between
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
49 them. This class is primarely designed to analyze gene-related
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
50 coordinate systems. See L<Bio::Coordinate::GeneMapper>.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
51
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
52 Note that this module can not be used to manage graphs.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
53
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
54 Technically the graph implemented here is known as Directed Acyclic
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
55 Graph (DAG). DAG is composed of vertices (nodes) and edges (with
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
56 optional weights) linking them. Nodes of the graph are the coordinate
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
57 systems in gene mapper.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
58
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
59 The shortest path is found using the Dijkstra's algorithm. This
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
60 algorithm is fast and greedy and requires all weights to be
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
61 positive. All weights in the gene coordinate system graph are
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
62 currently equal (1) making the graph unweighted. That makes the use of
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
63 Dijkstra's algorithm an overkill. A impler and faster breadth-first
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
64 would be enough. Luckily the difference for small graphs is not
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
65 signigicant and the implementation is capable to take weights into
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
66 account if needed at some later time.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
67
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
68 =head2 Input format
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
69
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
70 The graph needs to be primed using a hash of hashes where there is a
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
71 key for each node. The second keys are the names of the downstream
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
72 neighboring nodes and values are the weights for reaching them. Here
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
73 is part of the gene coordiante system graph::
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
74
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
75
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
76 $hash = {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
77 '6' => undef,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
78 '3' => {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
79 '6' => 1
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
80 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
81 '2' => {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
82 '6' => 1,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
83 '4' => 1,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
84 '3' => 1
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
85 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
86 '1' => {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
87 '2' => 1
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
88 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
89 '4' => {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
90 '5' => 1
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
91 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
92 '5' => undef
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
93 };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
94
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
95
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
96 Note that the names need to be positive integrers. Root should be '1'
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
97 and directness of the graph is taken advantage of to speed
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
98 calculations by assuming that downsream nodes always have larger
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
99 number as name.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
100
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
101 An alternative (shorter) way of describing input is to use hash of
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
102 arrays. See L<Bio::Coordinate::Graph::hash_of_arrays>.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
103
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
104
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
105 =head1 FEEDBACK
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
106
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
107 =head2 Mailing Lists
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
108
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
109 User feedback is an integral part of the evolution of this and other
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
110 Bioperl modules. Send your comments and suggestions preferably to the
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
111 Bioperl mailing lists Your participation is much appreciated.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
112
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
113 bioperl-l@bioperl.org - General discussion
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
114 http://bio.perl.org/MailList.html - About the mailing lists
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
115
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
116 =head2 Reporting Bugs
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
117
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
118 report bugs to the Bioperl bug tracking system to help us keep track
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
119 the bugs and their resolution. Bug reports can be submitted via
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
120 email or the web:
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
121
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
122 bioperl-bugs@bio.perl.org
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
123 http://bugzilla.bioperl.org/
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
124
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
125 =head1 AUTHOR - Heikki Lehvaslaiho
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
126
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
127 Email: heikki@ebi.ac.uk
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
128 Address:
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
129
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
130 EMBL Outstation, European Bioinformatics Institute
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
131 Wellcome Trust Genome Campus, Hinxton
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
132 Cambs. CB10 1SD, United Kingdom
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
133
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
134 =head1 APPENDIX
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
135
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
136 The rest of the documentation details each of the object
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
137 methods. Internal methods are usually preceded with a _
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
138
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
139 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
140
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
141
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
142 # Let the code begin...
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
143
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
144 package Bio::Coordinate::Graph;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
145 use vars qw(@ISA );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
146 use strict;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
147
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
148 # Object preamble - inherits from Bio::Root::Root
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
149 use Bio::Root::Root;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
150
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
151 @ISA = qw(Bio::Root::Root);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
152
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
153
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
154 sub new {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
155 my($class,@args) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
156 my $self = $class->SUPER::new(@args);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
157
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
158 my($graph, $hasharray) =
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
159 $self->_rearrange([qw(
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
160 GRAPH
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
161 HASHARRAY
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
162 )],
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
163 @args);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
164
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
165 $graph && $self->graph($graph);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
166 $hasharray && $self->hasharray($hasharray);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
167
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
168 $self->{'_root'} = undef;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
169
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
170 return $self; # success - we hope!
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
171
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
172 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
173
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
174 =head2 Graph structure input methods
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
175
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
176 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
177
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
178 =head2 graph
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
179
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
180 Title : graph
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
181 Usage : $obj->graph($my_graph)
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
182 Function: Read/write method for the graph structure
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
183 Example :
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
184 Returns : hash of hashes grah structure
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
185 Args : reference to a hash of hashes
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
186
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
187 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
188
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
189 sub graph {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
190
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
191 my ($self,$value) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
192
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
193 if ($value) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
194 $self->throw("Need a hash of hashes")
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
195 unless ref($value) eq 'HASH' ;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
196 $self->{'_dag'} = $value;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
197
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
198 # empty the cache
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
199 $self->{'_root'} = undef;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
200
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
201 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
202
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
203 return $self->{'_dag'};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
204
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
205 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
206
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
207
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
208 =head2 hash_of_arrays
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
209
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
210 Title : hash_of_arrays
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
211 Usage : $obj->hash_of_array(%hasharray)
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
212 Function: An alternative method to read in the graph structure.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
213 Hash arrays are easier to type. This method converts
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
214 arrays into hashes and assigns equal values "1" to
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
215 weights.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
216
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
217 Example : Here is an example of simple structure containing a graph.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
218
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
219 my $DAG = {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
220 6 => [],
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
221 5 => [],
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
222 4 => [5],
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
223 3 => [6],
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
224 2 => [3, 4, 6],
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
225 1 => [2]
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
226 };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
227
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
228 Returns : hash of hashes graph structure
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
229 Args : reference to a hash of arrays
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
230
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
231 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
232
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
233 sub hash_of_arrays {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
234
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
235 my ($self,$value) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
236
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
237 # empty the cache
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
238 $self->{'_root'} = undef;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
239
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
240 if ($value) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
241
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
242 $self->throw("Need a hash of hashes")
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
243 unless ref($value) eq 'HASH' ;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
244
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
245 #copy the hash of arrays into a hash of hashes;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
246 my %hash;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
247 foreach my $start ( keys %{$value}){
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
248 $hash{$start} = undef;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
249 map { $hash{$start}{$_} = 1 } @{$value->{$start}};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
250 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
251
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
252 $self->{'_dag'} = \%hash;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
253 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
254
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
255 return $self->{'_dag'};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
256
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
257 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
258
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
259 =head2 Methods for determining the shortest path in the graph
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
260
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
261 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
262
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
263 =head2 shortest_path
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
264
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
265 Title : shortest_path
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
266 Usage : $obj->shortest_path($a, $b);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
267 Function: Method for retrieving the shortest path between nodes.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
268 If the start node remains the same, the method is sometimes
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
269 able to use cached results, otherwise it will recalculate
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
270 the paths.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
271 Example :
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
272 Returns : array of node names, only the start node name if no path
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
273 Args : name of the start node
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
274 : name of the end node
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
275
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
276 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
277
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
278
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
279 sub shortest_path {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
280 my ($self, $root, $end) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
281
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
282 $self->throw("Two arguments needed") unless @_ == 3;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
283 $self->throw("No node name [$root]")
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
284 unless exists $self->{'_dag'}->{$root};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
285 $self->throw("No node name [$end]")
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
286 unless exists $self->{'_dag'}->{$end};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
287
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
288 my @res; # results
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
289 my $reverse;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
290
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
291 if ($root > $end) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
292 ($root, $end) = ($end, $root );
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
293 $reverse++;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
294 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
295
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
296 # try to use cached paths
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
297 $self->dijkstra($root) unless
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
298 defined $self->{'_root'} and $self->{'_root'} eq $root;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
299
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
300 return @res unless $self->{'_paths'} ;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
301
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
302 # create the list
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
303 my $node = $end;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
304 my $prev = $self->{'_paths'}->{$end}{'prev'};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
305 while ($prev) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
306 unshift @res, $node;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
307 $node = $self->{'_paths'}->{$node}{'prev'};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
308 $prev = $self->{'_paths'}->{$node}{'prev'};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
309 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
310 unshift @res, $node;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
311
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
312 $reverse ? return reverse @res : return @res;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
313 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
314
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
315
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
316 =head2 dijkstra
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
317
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
318 Title : dijkstra
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
319 Usage : $graph->dijkstra(1);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
320 Function: Implements Dijkstra's algorithm.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
321 Returns or sets a list of mappers. The returned path
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
322 description is always directed down from the root.
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
323 Called from shortest_path().
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
324 Example :
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
325 Returns : Reference to a hash of hashes representing a linked list
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
326 which contains shortest path down to all nodes from the start
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
327 node. E.g.:
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
328
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
329 $res = {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
330 '2' => {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
331 'prev' => '1',
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
332 'dist' => 1
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
333 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
334 '1' => {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
335 'prev' => undef,
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
336 'dist' => 0
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
337 },
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
338 };
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
339
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
340 Args : name of the start node
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
341
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
342 =cut
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
343
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
344 sub dijkstra {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
345 my ($self,$root) = @_;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
346
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
347 $self->throw("I need the name of the root node input") unless $root;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
348 $self->throw("No node name [$root]")
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
349 unless exists $self->{'_dag'}->{$root};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
350
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
351 my %est = (); # estimate hash
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
352 my %res = (); # result hash
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
353 my $nodes = keys %{$self->{'_dag'}};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
354 my $maxdist = 1000000;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
355
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
356 # cache the root value
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
357 $self->{'_root'} = $root;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
358
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
359 foreach my $node ( keys %{$self->{'_dag'}} ){
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
360 if ($node eq $root) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
361 $est{$node}{'prev'} = undef;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
362 $est{$node}{'dist'} = 0;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
363 } else {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
364 $est{$node}{'prev'} = undef;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
365 $est{$node}{'dist'} = $maxdist;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
366 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
367 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
368
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
369 # remove nodes from %est until it is empty
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
370 while (keys %est) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
371
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
372 #select the node closest to current one, or root node
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
373 my $min_node;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
374 my $min = $maxdist;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
375 foreach my $node (reverse sort keys %est) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
376 if ( $est{$node}{'dist'} < $min ) {
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
377 $min = $est{$node}{'dist'};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
378 $min_node = $node;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
379 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
380 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
381
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
382 # no more links between nodes
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
383 last unless ($min_node);
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
384
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
385 # move the node from %est into %res;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
386 $res{$min_node} = delete $est{$min_node};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
387
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
388 # recompute distances to the neighbours
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
389 my $dist = $res{$min_node}{'dist'};
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
390 foreach my $neighbour ( keys %{$self->{'_dag'}->{$min_node}} ){
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
391 next unless $est{$neighbour}; # might not be there any more
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
392 $est{$neighbour}{'prev'} = $min_node;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
393 $est{$neighbour}{'dist'} =
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
394 $dist + $self->{'_dag'}{$min_node}{$neighbour}
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
395 if $est{$neighbour}{'dist'} > $dist + 1 ;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
396 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
397 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
398 return $self->{'_paths'} = \%res;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
399 }
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
400
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
401
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
402 1;
1f6dce3d34e0 Uploaded
mahtabm
parents:
diff changeset
403