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 |
