This commit is contained in:
Xes
2025-08-14 22:41:49 +02:00
parent 2de81ccc46
commit 8ce45119b6
39774 changed files with 4309466 additions and 0 deletions

View File

@@ -0,0 +1,169 @@
<?php
use Fhaculty\Graph\Graph;
use Fhaculty\Graph\Vertex;
use Graphp\Algorithms\ShortestPath\Base as ShortestPathAlg;
abstract class BaseShortestPathTest extends TestCase
{
/**
*
* @param Vertex $vertex
* @return ShortestPathAlg
*/
abstract protected function createAlg(Vertex $vertex);
abstract public function testGraphParallelNegative();
public function testGraphTrivial()
{
// 1
$graph = new Graph();
$v1 = $graph->createVertex(1);
$alg = $this->createAlg($v1);
$this->assertFalse($alg->hasVertex($v1));
//$this->assertEquals(0, $alg->getDistance($v1));
$this->assertEquals(array(), $alg->getDistanceMap());
$this->assertEquals(array(), $alg->getEdges()->getVector());
//$this->assertEquals(array(), $alg->getEdgesTo($v1));
$this->assertEquals(array(), $alg->getVertices()->getVector());
$this->assertEquals(array(), $alg->getVertices()->getIds());
$clone = $alg->createGraph();
$this->assertGraphEquals($graph,$clone);
}
public function testGraphSingleLoop()
{
// 1 -[4]> 1
$graph = new Graph();
$v1 = $graph->createVertex(1);
$e1 = $v1->createEdgeTo($v1)->setWeight(4);
$alg = $this->createAlg($v1);
$this->assertEquals(array($e1), $alg->getEdges()->getVector());
$expectedWeight = $this->getExpectedWeight(array($e1));
$this->assertTrue($alg->hasVertex($v1));
$this->assertEquals($expectedWeight, $alg->getDistance($v1));
$this->assertEquals(array(1 => $expectedWeight), $alg->getDistanceMap());
$this->assertEquals(array($e1), $alg->getEdgesTo($v1)->getVector());
$this->assertEquals(array(1 => $v1), $alg->getVertices()->getMap());
$this->assertEquals(array(1), $alg->getVertices()->getIds());
}
public function testGraphCycle()
{
// 1 -[4]-> 2 -[2]-> 1
$graph = new Graph();
$v1 = $graph->createVertex(1);
$v2 = $graph->createVertex(2);
$e1 = $v1->createEdgeTo($v2)->setWeight(4);
$e2 = $v2->createEdgeTo($v1)->setWeight(2);
$alg = $this->createAlg($v1);
//$this->assertEquals(array($e2, $e1), $alg->getEdges());
$expectedWeight = $this->getExpectedWeight(array($e1));
$this->assertTrue($alg->hasVertex($v2));
$this->assertEquals(array($e1), $alg->getEdgesTo($v2)->getVector());
$this->assertEquals($expectedWeight, $alg->getDistance($v2));
$expectedWeight = $this->getExpectedWeight(array($e1, $e2));
$this->assertTrue($alg->hasVertex($v1));
$this->assertEquals(array($e1, $e2), $alg->getEdgesTo($v1)->getVector());
$this->assertEquals($expectedWeight, $alg->getDistance($v1));
$walk = $alg->getWalkTo($v1);
$this->assertEquals(2, \count($walk->getEdges()));
}
/**
* @expectedException OutOfBoundsException
*/
public function testIsolatedVertexIsNotReachable()
{
// 1, 2
$graph = new Graph();
$v1 = $graph->createVertex(1);
$v2 = $graph->createVertex(2);
$alg = $this->createAlg($v1);
$this->assertFalse($alg->hasVertex($v2));
$alg->getEdgesTo($v2);
}
/**
* @expectedException OutOfBoundsException
*/
public function testSeparateGraphsAreNotReachable()
{
// 1
$graph1 = new Graph();
$vg1 = $graph1->createVertex(1);
$graph2 = new Graph();
$vg2 = $graph2->createVertex(1);
$alg = $this->createAlg($vg1);
$alg->getEdgesTo($vg2);
}
public function testGraphUnweighted()
{
// 1 -> 2
$graph = new Graph();
$v1 = $graph->createVertex(1);
$v2 = $graph->createVertex(2);
$e1 = $v1->createEdgeTo($v2);
$alg = $this->createAlg($v1);
$expectedWeight = $this->getExpectedWeight(array($e1));
$this->assertEquals($expectedWeight, $alg->getDistance($v2));
$this->assertEquals(array(2 => $expectedWeight), $alg->getDistanceMap());
$this->assertEquals(array($e1), $alg->getEdges()->getVector());
$this->assertEquals(array($e1), $alg->getEdgesTo($v2)->getVector());
$this->assertEquals(array(2), $alg->getVertices()->getIds());
}
public function testGraphTwoComponents()
{
// 1 -[10]-> 2
// 3 -[20]-> 4
$graph = new Graph();
$v1 = $graph->createVertex(1);
$v2 = $graph->createVertex(2);
$v3 = $graph->createVertex(3);
$v4 = $graph->createVertex(4);
$e1 = $v1->createEdgeTo($v2)->setWeight(10);
$v3->createEdgeTo($v4)->setWeight(20);
$alg = $this->createAlg($v1);
$expectedWeight = $this->getExpectedWeight(array($e1));
$this->assertEquals($expectedWeight, $alg->getDistance($v2));
$this->assertEquals(array(2 => $expectedWeight), $alg->getDistanceMap());
$this->assertEquals(array($e1), $alg->getEdges()->getVector());
// $this->assertEquals(array(), $alg->getEdgesTo($v1));
$this->assertEquals(array($e1), $alg->getEdgesTo($v2)->getVector());
$this->assertEquals(array(2 => $v2), $alg->getVertices()->getMap());
$this->assertEquals(array(2), $alg->getVertices()->getIds());
}
protected function getExpectedWeight($edges)
{
$sum = 0;
foreach ($edges as $edge) {
$sum += $edge->getWeight();
}
return $sum;
}
}

View File

@@ -0,0 +1,39 @@
<?php
use Fhaculty\Graph\Graph;
use Fhaculty\Graph\Vertex;
use Graphp\Algorithms\ShortestPath\BreadthFirst;
class BreadthFirstTest extends BaseShortestPathTest
{
protected function createAlg(Vertex $vertex)
{
return new BreadthFirst($vertex);
}
public function testGraphParallelNegative()
{
// 1 -[10]-> 2
// | ^
// \--[-1]---/
$graph = new Graph();
$v1 = $graph->createVertex(1);
$v2 = $graph->createVertex(2);
$e1 = $v1->createEdgeTo($v2)->setWeight(10);
$v1->createEdgeTo($v2)->setWeight(-1);
$alg = $this->createAlg($v1);
$this->assertEquals(1, $alg->getDistance($v2));
$this->assertEquals(array(2 => 1), $alg->getDistanceMap());
$this->assertEquals(array($e1), $alg->getEdges()->getVector());
$this->assertEquals(array($e1), $alg->getEdgesTo($v2)->getVector());
$this->assertEquals(array(2 => $v2), $alg->getVertices()->getMap());
$this->assertEquals(array(2), $alg->getVertices()->getIds());
}
protected function getExpectedWeight($edges)
{
return \count($edges);
}
}

View File

@@ -0,0 +1,32 @@
<?php
use Fhaculty\Graph\Graph;
use Fhaculty\Graph\Vertex;
use Graphp\Algorithms\ShortestPath\Dijkstra;
class DijkstraTest extends BaseShortestPathTest
{
protected function createAlg(Vertex $vertex)
{
return new Dijkstra($vertex);
}
/**
* @expectedException UnexpectedValueException
*/
public function testGraphParallelNegative()
{
// 1 -[10]-> 2
// | ^
// \--[-1]---/
$graph = new Graph();
$v1 = $graph->createVertex(1);
$v2 = $graph->createVertex(2);
$v1->createEdgeTo($v2)->setWeight(10);
$v1->createEdgeTo($v2)->setWeight(-1);
$alg = $this->createAlg($v1);
$alg->getEdges();
}
}

View File

@@ -0,0 +1,111 @@
<?php
use Fhaculty\Graph\Graph;
use Fhaculty\Graph\Vertex;
use Graphp\Algorithms\ShortestPath\MooreBellmanFord;
class MooreBellmanFordTest extends BaseShortestPathTest
{
protected function createAlg(Vertex $vertex)
{
return new MooreBellmanFord($vertex);
}
public function testGraphParallelNegative()
{
// 1 -[10]-> 2
// | ^
// \--[-1]---/
$graph = new Graph();
$v1 = $graph->createVertex(1);
$v2 = $graph->createVertex(2);
$v1->createEdgeTo($v2)->setWeight(10);
$e2 = $v1->createEdgeTo($v2)->setWeight(-1);
$alg = $this->createAlg($v1);
// $this->assertEquals(0, $alg->getDistance($v1));
$this->assertEquals(-1, $alg->getDistance($v2));
$this->assertEquals(array(2 => -1), $alg->getDistanceMap());
$this->assertEquals(array($e2), $alg->getEdges()->getVector());
//$this->assertEquals(array(), $alg->getEdgesTo($v1));
$this->assertEquals(array($e2), $alg->getEdgesTo($v2)->getVector());
$this->assertEquals(array(2 => $v2), $alg->getVertices()->getMap());
$this->assertEquals(array(2), $alg->getVertices()->getIds());
return $alg;
}
/**
* @param MooreBellmanFord $alg
* @depends testGraphParallelNegative
* @expectedException UnderflowException
*/
public function testNoNegativeCycle(MooreBellmanFord $alg)
{
$alg->getCycleNegative();
}
public function testUndirectedNegativeWeightIsCycle()
{
// 1 -[-10]- 2
$graph = new Graph();
$v1 = $graph->createVertex(1);
$v2 = $graph->createVertex(2);
$v1->createEdge($v2)->setWeight(-10);
$alg = $this->createAlg($v1);
$cycle = $alg->getCycleNegative();
$this->assertInstanceOf('Fhaculty\Graph\Walk', $cycle);
}
public function testLoopNegativeWeightIsCycle()
{
// 1 -[-10]-> 1
$graph = new Graph();
$v1 = $graph->createVertex(1);
$v1->createEdge($v1)->setWeight(-10);
$alg = $this->createAlg($v1);
$cycle = $alg->getCycleNegative();
$this->assertInstanceOf('Fhaculty\Graph\Walk', $cycle);
}
public function testNegativeComponentHasCycle()
{
// 1 -[1]-> 2 3 --[-1]--> 4
// ^ |
// \---[-2]----/
$graph = new Graph();
$v1 = $graph->createVertex(1);
$v2 = $graph->createVertex(2);
$v3 = $graph->createVertex(3);
$v4 = $graph->createVertex(4);
$v1->createEdgeTo($v2)->setWeight(1);
$v3->createEdgeTo($v4)->setWeight(-1);
$v4->createEdgeTo($v3)->setWeight(-2);
// second component has a cycle
$alg = $this->createAlg($v3);
$cycle = $alg->getCycleNegative();
assert(isset($cycle));
// first component does not have a cycle
$alg = $this->createAlg($v1);
$this->expectException('UnderflowException');
$alg->getCycleNegative();
}
public function expectException($class)
{
if (\method_exists($this, 'setExpectedException')) {
$this->setExpectedException($class);
} else {
parent::expectException($class);
}
}
}