Skip to content

Commit

Permalink
Merge pull request #41 from clue/move-algo-symmetric
Browse files Browse the repository at this point in the history
Move Graph::isSymmetric() helper to new Algorithm\Symmetric
  • Loading branch information
clue committed Jun 7, 2013
2 parents 1f0b4b4 + 640468e commit 0bee8c8
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 24 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ you spot any mistakes.
* BC break: Move `Graph::getDegree()`, `Graph::getDegreeMin()`, `Graph::getDegreeMax()`, `Graph::isRegular()` and `Graph::isBalanced()` to new `Algorithm\Degree` (#29)
* BC break: Move `Graph::getBalance()` and `Graph::isBalancedFlow()` to new `Algorithm\Balance` (#30)
* BC break: Move `Set::isDirected()` to new `Algorithm\Directed` (#34)
* BC break: Move `Graph::isSymmetric()` to new `Algorithm\Symmetric` (#41)
* BC break: Remove unneeded algorithm alias definitions to reduce complexity, improve testability and avoid tight coupling (#31)
* `Graph::isConnected()` (=> `Algorithm\ConnectedComponents::isSingle()`)
* `Graph::hasEulerianCycle()` (=> `Algorithm\Eulerian::hasCycle()`)
Expand Down
60 changes: 60 additions & 0 deletions lib/Fhaculty/Graph/Algorithm/Symmetric.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace Fhaculty\Graph\Algorithm;

use Fhaculty\Graph\Edge\Directed as EdgeDirected;
use Fhaculty\Graph\Graph;
use Fhaculty\Graph\Vertex;

/**
* Basic algorithms for working with symmetric digraphs
*
* A directed graph is called symmetric if, for every arc that belongs to it,
* the corresponding reversed arc (antiparallel directed edge) also belongs to it.
*
* @link http://en.wikipedia.org/wiki/Directed_graph#Classes_of_digraphs
*/
class Symmetric extends Base
{
/**
* Graph to operate on
*
* @var Graph
*/
private $graph;

/**
* instantiate symmetric algorithm
*
* @param Graph $graph Graph
*/
public function __construct(Graph $graph)
{
$this->graph = $graph;
}

/**
* checks whether this graph is symmetric (for every edge a->b there's also an edge b->a)
*
* @return boolean
* @uses Graph::getEdges()
* @uses EdgeDirected::getVertexStart()
* @uses EdgeDirected::getVertedEnd()
* @uses Vertex::hasEdgeTo()
*/
public function isSymmetric()
{
// check all edges
foreach ($this->graph->getEdges() as $edge) {
// only check directed edges (undirected ones are symmetric by definition)
if ($edge instanceof EdgeDirected) {
// check if end also has an edge to start
if (!$edge->getVertexEnd()->hasEdgeTo($edge->getVertexStart())) {
return false;
}
}
}

return true;
}
}
24 changes: 0 additions & 24 deletions lib/Fhaculty/Graph/Graph.php
Original file line number Diff line number Diff line change
Expand Up @@ -328,30 +328,6 @@ public function isTrivial()
return (!$this->edges && count($this->vertices) === 1);
}

/**
* checks whether this graph is symmetric (for every edge a->b there's also an edge b->a)
*
* @return boolean
* @uses EdgeDirected::getVertexStart()
* @uses EdgeDirected::getVertedEnd()
* @uses Vertex::hasEdgeTo()
*/
public function isSymmetric()
{
// check all edges
foreach ($this->edges as $edge) {
// only check directed edges (undirected ones are symmetric by definition)
if ($edge instanceof EdgeDirected) {
// check if end also has an edge to start
if (!$edge->getVertexEnd()->hasEdgeTo($edge->getVertexStart())) {
return false;
}
}
}

return true;
}

/**
* checks whether this graph has any parallel edges (aka multigraph)
*
Expand Down
61 changes: 61 additions & 0 deletions tests/Fhaculty/Graph/Algorithm/SymmetricTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

use Fhaculty\Graph\Algorithm\Symmetric as AlgorithmSymmetric;
use Fhaculty\Graph\Graph;

class SymmetricTest extends TestCase
{
public function testGraphEmpty()
{
$graph = new Graph();

$alg = new AlgorithmSymmetric($graph);

$this->assertTrue($alg->isSymmetric());
}

public function testGraphIsolated()
{
$graph = new Graph();
$graph->createVertex(1);
$graph->createVertex(2);

$alg = new AlgorithmSymmetric($graph);

$this->assertTrue($alg->isSymmetric());
}

public function testGraphSingleArcIsNotSymmetricr()
{
// 1 -> 2
$graph = new Graph();
$graph->createVertex(1)->createEdgeTo($graph->createVertex(2));

$alg = new AlgorithmSymmetric($graph);

$this->assertFalse($alg->isSymmetric());
}

public function testGraphAntiparallelIsSymmetricr()
{
// 1 -> 2 -> 1
$graph = new Graph();
$graph->createVertex(1)->createEdgeTo($graph->createVertex(2));
$graph->getVertex(2)->createEdgeTo($graph->getVertex(1));

$alg = new AlgorithmSymmetric($graph);

$this->assertTrue($alg->isSymmetric());
}

public function testGraphSingleUndirectedIsSymmetricr()
{
// 1 -- 2
$graph = new Graph();
$graph->createVertex(1)->createEdge($graph->createVertex(2));

$alg = new AlgorithmSymmetric($graph);

$this->assertTrue($alg->isSymmetric());
}
}

0 comments on commit 0bee8c8

Please sign in to comment.