Mercurial > repos > deepakjadmin > mayatool3_test2
comparison lib/Graph/Path.pm @ 0:4816e4a8ae95 draft default tip
Uploaded
author | deepakjadmin |
---|---|
date | Wed, 20 Jan 2016 09:23:18 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4816e4a8ae95 |
---|---|
1 package Graph::Path; | |
2 # | |
3 # $RCSfile: Path.pm,v $ | |
4 # $Date: 2015/02/28 20:49:06 $ | |
5 # $Revision: 1.25 $ | |
6 # | |
7 # Author: Manish Sud <msud@san.rr.com> | |
8 # | |
9 # Copyright (C) 2015 Manish Sud. All rights reserved. | |
10 # | |
11 # This file is part of MayaChemTools. | |
12 # | |
13 # MayaChemTools is free software; you can redistribute it and/or modify it under | |
14 # the terms of the GNU Lesser General Public License as published by the Free | |
15 # Software Foundation; either version 3 of the License, or (at your option) any | |
16 # later version. | |
17 # | |
18 # MayaChemTools is distributed in the hope that it will be useful, but without | |
19 # any warranty; without even the implied warranty of merchantability of fitness | |
20 # for a particular purpose. See the GNU Lesser General Public License for more | |
21 # details. | |
22 # | |
23 # You should have received a copy of the GNU Lesser General Public License | |
24 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or | |
25 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330, | |
26 # Boston, MA, 02111-1307, USA. | |
27 # | |
28 | |
29 use strict; | |
30 use Carp; | |
31 use Exporter; | |
32 use Storable (); | |
33 use Scalar::Util (); | |
34 | |
35 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); | |
36 | |
37 @ISA = qw(Exporter); | |
38 @EXPORT = qw(); | |
39 @EXPORT_OK = qw(); | |
40 | |
41 %EXPORT_TAGS = (all => [@EXPORT, @EXPORT_OK]); | |
42 | |
43 # Setup class variables... | |
44 my($ClassName, $ObjectID); | |
45 _InitializeClass(); | |
46 | |
47 # Overload Perl functions... | |
48 use overload '""' => 'StringifyPath', | |
49 | |
50 '==' => '_PathEqualOperator', | |
51 'eq' => '_PathEqualOperator', | |
52 | |
53 'fallback' => undef; | |
54 | |
55 # Class constructor... | |
56 sub new { | |
57 my($Class, @VertexIDs) = @_; | |
58 | |
59 # Initialize object... | |
60 my $This = {}; | |
61 bless $This, ref($Class) || $Class; | |
62 $This->_InitializePath(); | |
63 | |
64 if (@VertexIDs) { $This->AddVertices(@VertexIDs); } | |
65 | |
66 return $This; | |
67 } | |
68 | |
69 # Initialize object data... | |
70 # | |
71 sub _InitializePath { | |
72 my($This) = @_; | |
73 | |
74 @{$This->{Vertices}} = (); | |
75 } | |
76 | |
77 # Initialize class ... | |
78 sub _InitializeClass { | |
79 #Class name... | |
80 $ClassName = __PACKAGE__; | |
81 } | |
82 | |
83 # Add a vertex to path after the end vertex... | |
84 # | |
85 sub AddVertex { | |
86 my($This, $VertexID) = @_; | |
87 | |
88 if (!defined $VertexID ) { | |
89 carp "Warning: ${ClassName}->AddVertex: No vertex added: Vertex ID must be specified..."; | |
90 return undef; | |
91 } | |
92 push @{$This->{Vertices}}, $VertexID; | |
93 | |
94 return $This; | |
95 } | |
96 | |
97 # Add vertices to the path after the end vertex... | |
98 # | |
99 sub AddVertices { | |
100 my($This, @VertexIDs) = @_; | |
101 | |
102 if (!@VertexIDs) { | |
103 carp "Warning: ${ClassName}->AddVertices: No vertices added: Vertices list is empty..."; | |
104 return undef; | |
105 } | |
106 push @{$This->{Vertices}}, @VertexIDs; | |
107 | |
108 return $This; | |
109 } | |
110 | |
111 # Add a vertex to path after the end vertex... | |
112 # | |
113 sub PushVertex { | |
114 my($This, $VertexID) = @_; | |
115 | |
116 return $This->AddVertex($VertexID); | |
117 } | |
118 | |
119 # Add vertices to the path after the end vertex... | |
120 # | |
121 sub PushVertices { | |
122 my($This, @VertexIDs) = @_; | |
123 | |
124 return $This->AddVertices(@VertexIDs); | |
125 } | |
126 | |
127 # Remove end vertex from path... | |
128 # | |
129 sub PopVertex { | |
130 my($This) = @_; | |
131 | |
132 if (!@{$This->{Vertices}}) { | |
133 carp "Warning: ${ClassName}->PopVertex: No vertex removed: Path is empty..."; | |
134 return undef; | |
135 } | |
136 pop @{$This->{Vertices}}; | |
137 | |
138 return $This; | |
139 } | |
140 | |
141 # Remove start vertex from path... | |
142 # | |
143 sub ShiftVertex { | |
144 my($This) = @_; | |
145 | |
146 if (!@{$This->{Vertices}}) { | |
147 carp "Warning: ${ClassName}->ShiftVertex: No vertex removed: Path is empty..."; | |
148 return undef; | |
149 } | |
150 shift @{$This->{Vertices}}; | |
151 | |
152 return $This; | |
153 } | |
154 | |
155 # Add a vertex to path before the start vertex... | |
156 # | |
157 sub UnshiftVertex { | |
158 my($This, $VertexID) = @_; | |
159 | |
160 if (!defined $VertexID ) { | |
161 carp "Warning: ${ClassName}->UnshiftVertex: No vertex added: Vertex ID must be specified..."; | |
162 return undef; | |
163 } | |
164 unshift @{$This->{Vertices}}, $VertexID; | |
165 | |
166 return $This; | |
167 } | |
168 | |
169 # Add vertices to the path before the start vertex... | |
170 # | |
171 sub UnshiftVertices { | |
172 my($This, @VertexIDs) = @_; | |
173 | |
174 if (!@VertexIDs) { | |
175 carp "Warning: ${ClassName}->UnshiftVertices: No vertices added: Vertices list is empty..."; | |
176 return undef; | |
177 } | |
178 unshift @{$This->{Vertices}}, @VertexIDs; | |
179 | |
180 return $This; | |
181 } | |
182 | |
183 # Get length... | |
184 # | |
185 sub GetLength { | |
186 my($This) = @_; | |
187 | |
188 return scalar @{$This->{Vertices}}; | |
189 } | |
190 | |
191 # Get start vertex... | |
192 # | |
193 sub GetStartVertex { | |
194 my($This) = @_; | |
195 | |
196 if (!$This->GetLength()) { | |
197 return undef; | |
198 } | |
199 my($Index) = 0; | |
200 return $This->_GetVertex($Index); | |
201 } | |
202 | |
203 # Get end vertex... | |
204 # | |
205 sub GetEndVertex { | |
206 my($This) = @_; | |
207 | |
208 if (!$This->GetLength()) { | |
209 return undef; | |
210 } | |
211 my($Index); | |
212 | |
213 $Index = $This->GetLength() - 1; | |
214 return $This->_GetVertex($Index); | |
215 } | |
216 | |
217 # Get start and end vertices... | |
218 # | |
219 sub GetTerminalVertices { | |
220 my($This) = @_; | |
221 | |
222 return ( $This->GetStartVertex(), $This->GetEndVertex() ), | |
223 } | |
224 | |
225 # Get path vertices... | |
226 # | |
227 sub GetVertices { | |
228 my($This) = @_; | |
229 | |
230 return wantarray ? @{$This->{Vertices}} : scalar @{$This->{Vertices}}; | |
231 } | |
232 | |
233 # Get a specific vertex from path with indicies starting from 0... | |
234 # | |
235 sub GetVertex { | |
236 my($This, $Index) = @_; | |
237 | |
238 if ($Index < 0) { | |
239 croak "Error: ${ClassName}->GetValue: Index value must be a positive number..."; | |
240 } | |
241 if ($Index >= $This->GetLength()) { | |
242 croak "Error: ${ClassName}->GetValue: Index vaue must be less than length of path..."; | |
243 } | |
244 if (!$This->GetLength()) { | |
245 return undef; | |
246 } | |
247 return $This->_GetVertex($Index); | |
248 } | |
249 | |
250 # Get a vertex... | |
251 # | |
252 sub _GetVertex { | |
253 my($This, $Index) = @_; | |
254 | |
255 return $This->{Vertices}[$Index]; | |
256 } | |
257 | |
258 # Get path edges as pair of vertices or number of edges... | |
259 # | |
260 sub GetEdges { | |
261 my($This) = @_; | |
262 | |
263 if ($This->GetLength < 1) { | |
264 return undef; | |
265 } | |
266 # Set up edges... | |
267 my($Index, $VertexID1, $VertexID2, @Vertices, @Edges); | |
268 | |
269 @Edges = (); | |
270 for $Index (0 .. ($#{$This->{Vertices}} - 1) ) { | |
271 $VertexID1 = $This->{Vertices}[$Index]; | |
272 $VertexID2 = $This->{Vertices}[$Index + 1]; | |
273 push @Edges, ($VertexID1, $VertexID2); | |
274 } | |
275 | |
276 return wantarray ? @Edges : ((scalar @Edges)/2); | |
277 } | |
278 | |
279 # Is it a cycle? | |
280 # | |
281 sub IsCycle { | |
282 my($This) = @_; | |
283 my($StartVertex, $EndVertex); | |
284 | |
285 ($StartVertex, $EndVertex) = $This->GetTerminalVertices(); | |
286 | |
287 return ($StartVertex == $EndVertex) ? 1 : 0; | |
288 } | |
289 | |
290 # For a path to be an independent path, it must meet the following conditions: | |
291 # . All other vertices are unique. | |
292 # | |
293 sub IsIndependentPath { | |
294 my($This) = @_; | |
295 | |
296 # Make sure it has at least two vertices... | |
297 if ($This->GetLength() < 2) { | |
298 return 0; | |
299 } | |
300 | |
301 # Check frequency of occurence for non-terminal vertices... | |
302 my($VertexID, $IndependenceStatus, @Vertices, %VerticesMap); | |
303 | |
304 @Vertices = $This->GetVertices(); | |
305 shift @Vertices; pop @Vertices; | |
306 | |
307 %VerticesMap = (); | |
308 $IndependenceStatus = 1; | |
309 | |
310 VERTEXID: for $VertexID (@Vertices) { | |
311 if (exists $VerticesMap{$VertexID} ) { | |
312 $IndependenceStatus = 0; | |
313 last VERTEXID; | |
314 } | |
315 $VerticesMap{$VertexID} = $VertexID; | |
316 } | |
317 return $IndependenceStatus; | |
318 } | |
319 | |
320 # For a path to be an independent cyclic path, it must meet the following conditions: | |
321 # . Termimal vertices are the same | |
322 # . All other vertices are unique. | |
323 # | |
324 sub IsIndependentCyclicPath { | |
325 my($This) = @_; | |
326 | |
327 # Make sure it's a cycle... | |
328 if (!($This->GetLength() >= 3 && $This->IsCycle())) { | |
329 return 0; | |
330 } | |
331 return $This->IsIndependentPath(); | |
332 } | |
333 | |
334 # Is it a path object? | |
335 sub IsPath ($) { | |
336 my($Object) = @_; | |
337 | |
338 return _IsPath($Object); | |
339 } | |
340 | |
341 # Copy path... | |
342 # | |
343 sub Copy { | |
344 my($This) = @_; | |
345 my($NewPath); | |
346 | |
347 $NewPath = Storable::dclone($This); | |
348 | |
349 return $NewPath; | |
350 } | |
351 | |
352 # Reverse order of vertices in path... | |
353 # | |
354 sub Reverse { | |
355 my($This) = @_; | |
356 my(@VertexIDs); | |
357 | |
358 @VertexIDs = (); push @VertexIDs, @{$This->{Vertices}}; | |
359 | |
360 @{$This->{Vertices}} = (); push @{$This->{Vertices}}, reverse @VertexIDs; | |
361 | |
362 return $This; | |
363 } | |
364 | |
365 # Get vertices common between two paths... | |
366 # | |
367 sub GetCommonVertices { | |
368 my($This, $Other) = @_; | |
369 my($VertexID, @CommonVertices, %OtherVerticesMap); | |
370 | |
371 # Setup a vertices hash for a quick look up... | |
372 %OtherVerticesMap = (); | |
373 for $VertexID ($Other->GetVertices()) { | |
374 $OtherVerticesMap{$VertexID} = $VertexID; | |
375 } | |
376 | |
377 @CommonVertices = (); | |
378 for $VertexID ($This->GetVertices()) { | |
379 if ($OtherVerticesMap{$VertexID}) { | |
380 push @CommonVertices, $VertexID | |
381 } | |
382 } | |
383 return wantarray ? @CommonVertices : scalar @CommonVertices; | |
384 } | |
385 | |
386 # Join the existing path with a new path specifed using a path object of a list of | |
387 # verticies. | |
388 # | |
389 sub Join { | |
390 my($This, @Values) = @_; | |
391 | |
392 return $This->_Join(@Values); | |
393 } | |
394 | |
395 # Join the existing path with a new path specifed using a path object at a specified | |
396 # vertex. | |
397 # | |
398 sub JoinAtVertex { | |
399 my($This, $Other, $CenterVertexID) = @_; | |
400 | |
401 # Make sure CenterVertexID is end vertex in This and start vertex in Other before | |
402 # joining them... | |
403 if ($This->GetEndVertex() != $CenterVertexID) { | |
404 $This->Reverse(); | |
405 } | |
406 if ($Other->GetStartVertex() != $CenterVertexID) { | |
407 $Other->Reverse(); | |
408 } | |
409 return $This->_Join($Other); | |
410 } | |
411 | |
412 # Join the existing path with a new path specifed using a path object of a list of | |
413 # verticies. | |
414 # | |
415 # Notes: | |
416 # . Paths must have a common terminal vertex. | |
417 # . Based on the common terminal vertex found, new path vertices are added to the | |
418 # current path in one of the four ways: | |
419 # . New path at end of current path with same vertices order : EndVertex = NewStartVertex | |
420 # . New path at end of current path with reversed vertices order: EndVertex = NewEndVertex | |
421 # . New path at front of current path with same vertices order: StartVertex = NewEndVertex | |
422 # . New path at front of current path with reversed vertices order: StartVertex = NewStartVertex | |
423 # | |
424 sub _Join { | |
425 my($This, @Values) = @_; | |
426 | |
427 if (!@Values) { | |
428 return; | |
429 } | |
430 | |
431 # Get a list of new vertex IDs.. | |
432 my($NewPath, $FirstValue, $TypeOfFirstValue, @NewVertexIDs); | |
433 | |
434 $NewPath = $This->Copy(); | |
435 | |
436 @NewVertexIDs = (); | |
437 $FirstValue = $Values[0]; | |
438 $TypeOfFirstValue = ref $FirstValue; | |
439 if ($TypeOfFirstValue =~ /^(SCALAR|HASH|CODE|REF|GLOB)/) { | |
440 croak "Error: ${ClassName}->JoinPath: Trying to add vertices to path object with a reference to unsupported value format..."; | |
441 } | |
442 | |
443 if (_IsPath($FirstValue)) { | |
444 # It's another path object... | |
445 push @NewVertexIDs, @{$FirstValue->{Vertices}}; | |
446 } | |
447 elsif ($TypeOfFirstValue =~ /^ARRAY/) { | |
448 # It's array reference... | |
449 push @NewVertexIDs, @{$FirstValue}; | |
450 } | |
451 else { | |
452 # It's a list of values... | |
453 push @NewVertexIDs, @Values; | |
454 } | |
455 my($StartVertex, $EndVertex, $NewStartVertex, $NewEndVertex); | |
456 | |
457 ($StartVertex, $EndVertex) = $NewPath->GetTerminalVertices(); | |
458 ($NewStartVertex, $NewEndVertex) = ($NewVertexIDs[0], $NewVertexIDs[$#NewVertexIDs]); | |
459 | |
460 if (!($EndVertex == $NewStartVertex || $EndVertex == $NewEndVertex || $StartVertex == $NewEndVertex || $StartVertex == $NewStartVertex)) { | |
461 carp "Warning: ${ClassName}->JoinPath: Paths can't be joined: No common terminal vertex found..."; | |
462 return undef; | |
463 } | |
464 | |
465 if ($EndVertex == $NewStartVertex) { | |
466 # Take out EndVertex and add new path at the end... | |
467 pop @{$NewPath->{Vertices}}; | |
468 push @{$NewPath->{Vertices}}, @NewVertexIDs; | |
469 } | |
470 elsif ($EndVertex == $NewEndVertex) { | |
471 # Take out EndVertex and add new path at the end with reversed vertex order... | |
472 pop @{$NewPath->{Vertices}}; | |
473 push @{$NewPath->{Vertices}}, reverse @NewVertexIDs; | |
474 } | |
475 elsif ($StartVertex == $NewEndVertex) { | |
476 # Take out NewEndVertex and add new path at the front... | |
477 pop @NewVertexIDs; | |
478 unshift @{$NewPath->{Vertices}}, @NewVertexIDs; | |
479 } | |
480 elsif ($StartVertex == $NewStartVertex) { | |
481 # Take out NewStartVertex and add new path at the front... | |
482 shift @NewVertexIDs; | |
483 unshift @{$NewPath->{Vertices}}, reverse @NewVertexIDs; | |
484 } | |
485 | |
486 return $NewPath, | |
487 } | |
488 | |
489 # Compare two paths... | |
490 # | |
491 sub _PathEqualOperator { | |
492 my($This, $Other) = @_; | |
493 | |
494 if (!(defined($This) && _IsPath($This) && defined($Other) && _IsPath($Other))) { | |
495 croak "Error: ${ClassName}->_PathEqualOperator: Path equal comparison failed: Both object must be paths..."; | |
496 } | |
497 | |
498 if ($This->GetLength() != $Other->GetLength()) { | |
499 return 0; | |
500 } | |
501 my($ThisID, $OtherID, $ReverseOtherID); | |
502 | |
503 $ThisID = join('-', @{$This->{Vertices}}); | |
504 $OtherID = join('-', @{$Other->{Vertices}}); | |
505 $ReverseOtherID = join('-', reverse(@{$Other->{Vertices}})); | |
506 | |
507 return ($ThisID =~ /^($OtherID|$ReverseOtherID)$/) ? 1 : 0; | |
508 } | |
509 | |
510 # Return a string containing vertices in the path... | |
511 sub StringifyPath { | |
512 my($This) = @_; | |
513 my($PathString); | |
514 | |
515 $PathString = "Path: " . join('-', @{$This->{Vertices}}); | |
516 | |
517 return $PathString; | |
518 } | |
519 | |
520 # Is it a path object? | |
521 sub _IsPath { | |
522 my($Object) = @_; | |
523 | |
524 return (Scalar::Util::blessed($Object) && $Object->isa($ClassName)) ? 1 : 0; | |
525 } | |
526 | |
527 1; | |
528 | |
529 __END__ | |
530 | |
531 =head1 NAME | |
532 | |
533 Path - Path class | |
534 | |
535 =head1 SYNOPSIS | |
536 | |
537 use Graph::Path; | |
538 | |
539 use Graph::Path qw(:all); | |
540 | |
541 =head1 DESCRIPTION | |
542 | |
543 B<Path> class provides the following methods: | |
544 | |
545 new, AddVertex, AddVertices, Copy, GetCommonVertices, GetEdges, GetEndVertex, | |
546 GetLength, GetStartVertex, GetTerminalVertices, GetVertex, GetVertices, IsCycle, | |
547 IsIndependentCyclicPath, IsIndependentPath, IsPath, Join, JoinAtVertex, PopVertex, | |
548 PushVertex, PushVertices, Reverse, ShiftVertex, StringifyPath, UnshiftVertex, | |
549 UnshiftVertices | |
550 | |
551 Path is a sequential list of vertices with an edge between two successive vertices. The path | |
552 becomes a cycle when start vertex and end vertex are the same. | |
553 | |
554 The following operators are overloaded: | |
555 | |
556 "" == eq | |
557 | |
558 =head2 METHODS | |
559 | |
560 =over 4 | |
561 | |
562 =item B<new> | |
563 | |
564 $NewPath = new Path(); | |
565 $NewPath = new Path(@VertexIDs); | |
566 | |
567 Using specified I<VertexIDs>, B<new> method creates a new B<Path> object and returns | |
568 newly created B<Path> object. | |
569 | |
570 =item B<AddVertex> | |
571 | |
572 $Path->AddVertex($VertexID); | |
573 | |
574 Adds I<VertexID> to I<Path> and returns I<Path>. | |
575 | |
576 =item B<AddVertices> | |
577 | |
578 $Path->AddVertices(@VertexIDs); | |
579 | |
580 Adds vertices using I<VertexIDs> to I<Path> and returns I<Graph>. | |
581 | |
582 =item B<Copy> | |
583 | |
584 $Return = $Path->Copy(); | |
585 | |
586 Copies I<Path> and its associated data using B<Storable::dclone> and returns a new | |
587 B<Path> object. | |
588 | |
589 =item B<GetCommonVertices> | |
590 | |
591 @CommonVertices = $Path->GetCommonVertices($OtherPath); | |
592 $NumOfCommonVertices = $Path->GetCommonVertices($OtherPath); | |
593 | |
594 Returns an array containing common vertex IDs between two paths. In scalar context, number | |
595 of common vertices is returned. | |
596 | |
597 =item B<GetEdges> | |
598 | |
599 @EdgesVertexIDs = $Path->GetEdges(); | |
600 $NumOfEdges = $Path->GetEdges(); | |
601 | |
602 Returns an array containg successive paris of vertex IDs corresponding to all edges in I<Path>. | |
603 In scalar context, the number of edges is returned. | |
604 | |
605 =item B<GetEndVertex> | |
606 | |
607 $VertexID = $Path->GetEndVertex(); | |
608 | |
609 Returns B<VertexID> of end vertex in I<Path>. | |
610 | |
611 =item B<GetLength> | |
612 | |
613 $Length = $Path->GetLength(); | |
614 | |
615 Returns B<Length> of I<Path> corresponding to number of vertices in I<Path>. | |
616 | |
617 =item B<GetStartVertex> | |
618 | |
619 $VertexID = $Path->GetStartVertex(); | |
620 | |
621 Returns B<VertexID> of start vertex in I<Path>. | |
622 | |
623 =item B<GetTerminalVertices> | |
624 | |
625 ($StartVertexID, $EndVertexID) = $Path->GetTerminalVertices(); | |
626 | |
627 Returns vertex IDs of start and end vertices in I<Path>. | |
628 | |
629 =item B<GetVertex> | |
630 | |
631 $VertexID = $Path->GetVertex($Index); | |
632 | |
633 Returns specific vertex ID from I<Path> corresponding to I<Index> with indicies starting from 0. | |
634 | |
635 =item B<GetVertices> | |
636 | |
637 @Vertices = $Path->GetVertices(); | |
638 $NumOfVertices = $Path->GetVertices(); | |
639 | |
640 Returns an array containing all vertex IDs in I<Path>. In scalar context, number of vertices | |
641 is returned. | |
642 | |
643 =item B<IsCycle> | |
644 | |
645 $Status = $Path->IsCycle(); | |
646 | |
647 Returns 1 or 0 based on whether I<Path> is a B<CyclicPath> which has the same start and | |
648 end vertex IDs. | |
649 | |
650 =item B<IsIndependentCyclicPath> | |
651 | |
652 $Status = $Path->IsIndependentCyclicPath(); | |
653 | |
654 Returns 1 or 0 based on whether I<Path> is an independent B<CyclicPath>. For a I<Path> to be | |
655 an independent cyclic path, it must be a cyclic path and have unique vertices. | |
656 | |
657 =item B<IsIndependentPath> | |
658 | |
659 $Status = $Path->IsIndependentPath(); | |
660 | |
661 Returns 1 or 0 based on whether I<Path> is an independent B<Path>. For a I<Path> to be | |
662 an independent path, it must have unique vertices. | |
663 | |
664 =item B<IsPath> | |
665 | |
666 $Status = Graph::Path::IsPath(); | |
667 | |
668 Returns 1 or 0 based on whether I<Object> is a B<Path> object | |
669 | |
670 =item B<Join> | |
671 | |
672 $NewPath = $Path->Join($OtherPath); | |
673 $NewPath = $Path->Join(@VertexIDs); | |
674 | |
675 Joins existing I<Path> with a new path specified as a I<OtherPath> object or an array of I<VertexIDs> | |
676 and returns I<NewPath>. | |
677 | |
678 In order to successfully join two paths, terminal vertices must have a common vertex. Based on the | |
679 common terminal vertex found, additional path vertices are added to the current I<Path> in one of | |
680 the following four ways: | |
681 | |
682 . EndVertex = NewStartVertex: New path at end of current path with | |
683 same vertices order | |
684 | |
685 . EndVertex = NewEndVertex: New path at end of current path with | |
686 reversed vertices order | |
687 | |
688 . StartVertex = NewEndVertex: New path at front of current path | |
689 with same vertices order | |
690 | |
691 . StartVertex = NewStartVertex: New path at front of current path | |
692 with reversed vertices order | |
693 | |
694 =item B<JoinAtVertex> | |
695 | |
696 $NewPath = $Path->JoinAtVertex($OtherPath, $CenterVertexID); | |
697 | |
698 Joins existing I<Path> with I<OtherPath> at a specified I<CeterVertexID> and returns a I<NewPath>. | |
699 | |
700 =item B<PopVertex> | |
701 | |
702 $Path->PopVertex(); | |
703 | |
704 Removes end vertex from I<Path> and returns I<Path>. | |
705 | |
706 =item B<PushVertex> | |
707 | |
708 $Path->PushVertex($VertexID); | |
709 | |
710 Adds I<VertexID> to I<Path> after end vertex and returns I<Path>. | |
711 | |
712 =item B<PushVertices> | |
713 | |
714 $Path->PushVertices(@VertexIDs); | |
715 | |
716 Adds I<VertexIDs> to I<Path> after end vertex and returns I<Path>. | |
717 | |
718 =item B<Reverse> | |
719 | |
720 $Path->Reverse(); | |
721 | |
722 Reverses order of vertices in I<Path> and returns I<Path>. | |
723 | |
724 =item B<ShiftVertex> | |
725 | |
726 $Path->ShiftVertex(); | |
727 | |
728 Removes start vertex from I<Path> and returns I<Path>. | |
729 | |
730 =item B<StringifyPath> | |
731 | |
732 $String = $Path->StringifyPath(); | |
733 | |
734 Returns a string containing information about I<Path> object. | |
735 | |
736 =item B<UnshiftVertex> | |
737 | |
738 $Path->UnshiftVertex($VertexID); | |
739 | |
740 Adds I<VertexID> to I<Path> before start vertex and returns I<Path>. | |
741 | |
742 =item B<UnshiftVertices> | |
743 | |
744 $Path->UnshiftVertices(@VertexIDs); | |
745 | |
746 Adds I<VertexIDs> to I<Path> before start vertex and returns I<Path>. | |
747 | |
748 =back | |
749 | |
750 =head1 AUTHOR | |
751 | |
752 Manish Sud <msud@san.rr.com> | |
753 | |
754 =head1 SEE ALSO | |
755 | |
756 PathGraph.pm, PathsTraversal.pm | |
757 | |
758 =head1 COPYRIGHT | |
759 | |
760 Copyright (C) 2015 Manish Sud. All rights reserved. | |
761 | |
762 This file is part of MayaChemTools. | |
763 | |
764 MayaChemTools is free software; you can redistribute it and/or modify it under | |
765 the terms of the GNU Lesser General Public License as published by the Free | |
766 Software Foundation; either version 3 of the License, or (at your option) | |
767 any later version. | |
768 | |
769 =cut |