programming-examples/php/Algo/Parallel.php

85 lines
2.3 KiB
PHP
Raw Normal View History

2019-11-15 12:59:38 +01:00
<?php
namespace Graphp\Algorithms;
use Graphp\Algorithms\BaseGraph;
use Fhaculty\Graph\Edge\Base as Edge;
use Fhaculty\Graph\Edge\Directed as DirectedEdge;
use Fhaculty\Graph\Set\Edges;
use Fhaculty\Graph\Graph;
use LogicException;
/**
* Basic algorithms for working with parallel edges
*
* Parallel edges (also called multiple edges or a multi-edge), are two or more
* edges that are incident to the same two vertices. A simple graph has no
* multiple edges.
*
* @link http://en.wikipedia.org/wiki/Multiple_edges
*/
class Parallel extends BaseGraph
{
/**
* checks whether this graph has any parallel edges (aka multigraph)
*
* @return boolean
* @uses Edge::hasEdgeParallel() for every edge
*/
public function hasEdgeParallel()
{
foreach ($this->graph->getEdges() as $edge) {
if ($this->hasEdgeParallelEdge($edge)) {
return true;
}
}
return false;
}
/**
* checks whether this edge has any parallel edges
*
* @return boolean
* @uses Edge::getEdgesParallel()
*/
public function hasEdgeParallelEdge(Edge $edge)
{
return !$this->getEdgesParallelEdge($edge)->isEmpty();
}
/**
* get set of all Edges parallel to this edge (excluding self)
*
* @param Edge $edge
* @return Edges
* @throws LogicException
*/
public function getEdgesParallelEdge(Edge $edge)
{
if ($edge instanceof DirectedEdge) {
// get all edges between this edge's endpoints
$edges = $edge->getVertexStart()->getEdgesTo($edge->getVertexEnd())->getVector();
} else {
// edge points into both directions (undirected/bidirectional edge)
// also get all edges in other direction
$ends = $edge->getVertices();
$edges = $ends->getVertexFirst()->getEdges()->getEdgesIntersection($ends->getVertexLast()->getEdges())->getVector();
}
$pos = array_search($edge, $edges, true);
if ($pos === false) {
// @codeCoverageIgnoreStart
throw new LogicException('Internal error: Current edge not found');
// @codeCoverageIgnoreEnd
}
// exclude current edge from parallel edges
unset($edges[$pos]);
return new Edges(array_values($edges));
}
}