Skip to content

Commit

Permalink
all tests passing again
Browse files Browse the repository at this point in the history
  • Loading branch information
sporchia committed May 3, 2020
1 parent 105a02d commit 2d5d976
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 35 deletions.
1 change: 0 additions & 1 deletion src/Contracts/MinimumSpanningTree.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace PHGraph\Contracts;

use PHGraph\Graph;
use PHGraph\Support\EdgeCollection;

interface MinimumSpanningTree
{
Expand Down
5 changes: 2 additions & 3 deletions src/Contracts/TravelingSalesman.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace PHGraph\Contracts;

use PHGraph\Graph;
use PHGraph\Support\EdgeCollection;

interface TravelingSalesman
{
Expand All @@ -17,7 +16,7 @@ public function createGraph(): Graph;
/**
* Get all the edges in the path.
*
* @return \PHGraph\Support\EdgeCollection<\PHGraph\Edge>
* @return \PHGraph\Edge[]
*/
public function getEdges(): EdgeCollection;
public function getEdges(): array;
}
2 changes: 1 addition & 1 deletion src/ShortestPath/Dijkstra.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Dijkstra implements ShortestPath
{
/** @var \PHGraph\Vertex */
protected $vertex;
/** @var \PHGraph\Support\EdgeCollection */
/** @var \PHGraph\Edge[] */
protected $edges;

/**
Expand Down
32 changes: 17 additions & 15 deletions src/TravelingSalesman/NearestNeighbor.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@

use PHGraph\Contracts\TravelingSalesman;
use PHGraph\Graph;
use PHGraph\Support\EdgeCollection;
use PHGraph\Support\VertexCollection;
use PHGraph\Vertex;
use RuntimeException;
use SplObjectStorage;
use SplPriorityQueue;
use UnexpectedValueException;

Expand All @@ -34,7 +33,10 @@ class NearestNeighbor implements TravelingSalesman
public function __construct(Graph $graph)
{
$this->graph = $graph;
$this->start_vertex = $graph->getVertices()->random();
$vertices = $graph->getVertices();
$this->start_vertex = count($vertices)
? $vertices[array_rand($vertices)]
: null;
}

/**
Expand Down Expand Up @@ -66,23 +68,23 @@ public function createGraph(): Graph
*
* @throws UnexpectedValueException if the Graph is not connected
*
* @return \PHGraph\Support\EdgeCollection<\PHGraph\Edge>
* @return \PHGraph\Edge[]
*/
public function getEdges(): EdgeCollection
public function getEdges(): array
{
if ($this->start_vertex === null) {
throw new UnexpectedValueException('Graph is empty');
}

$edges = new EdgeCollection();
$edges = [];

$vertex_current = $this->start_vertex;
$marked = new VertexCollection();
$marked = new SplObjectStorage;

$itterations = $this->graph->getVertices()->count() - 1;
$itterations = count($this->graph->getVertices()) - 1;

for ($i = 0; $i < $itterations; $i++) {
$marked->add($vertex_current);
$marked->attach($vertex_current);

$edge_queue = new SplPriorityQueue();

Expand All @@ -102,7 +104,7 @@ public function getEdges(): EdgeCollection
}
} while ($marked->contains($cheapest_edge->getFrom()) && $marked->contains($cheapest_edge->getTo()));

$edges[] = $cheapest_edge;
$edges[$cheapest_edge->getId()] = $cheapest_edge;

if ($marked->contains($cheapest_edge->getFrom())) {
$vertex_current = $cheapest_edge->getTo();
Expand All @@ -112,24 +114,24 @@ public function getEdges(): EdgeCollection
}

// try to connect back to start vertex
if ($vertex_current->getVertices()->contains($this->start_vertex)) {
if ($vertex_current->getVertices()[$this->start_vertex->getId()] ?? false) {
$edge_queue = new SplPriorityQueue();
/** @var \PHGraph\Edge $edge */
foreach ($vertex_current->getEdgesOut() as $edge) {
if (!$edge->isLoop() && !$edges->contains($edge)) {
if (!$edge->isLoop() && !($edges[$edge->getId()] ?? false)) {
$edge_queue->insert($edge, -$edge->getAttribute('weight', 0));
}
}

do {
/** @var \PHGraph\Edge $cheapest_edge */
$cheapest_edge = $edge_queue->extract();
} while (!$cheapest_edge->getVertices()->contains($this->start_vertex));
} while (!($cheapest_edge->getVertices()[$this->start_vertex->getId()] ?? false));

$edges[] = $cheapest_edge;
$edges[$cheapest_edge->getId()] = $cheapest_edge;
}

if ($edges->count() !== (count($this->graph->getVertices()))) {
if (count($edges) !== (count($this->graph->getVertices()))) {
throw new UnexpectedValueException('Graph is not connected');
}

Expand Down
14 changes: 14 additions & 0 deletions tests/MinimumSpanningTree/PrimTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ public function testInstantiation(): void
$this->assertInstanceOf(Prim::class, new Prim(new Graph));
}


/**
* @covers PHGraph\MinimumSpanningTree\Prim::__construct
*
* @return void
*/
public function testInstantiationWithVertices(): void
{
$g = new Graph;
$g->newVertex();

$this->assertInstanceOf(Prim::class, new Prim($g));
}

/**
* @covers PHGraph\MinimumSpanningTree\Prim::__construct
*
Expand Down
2 changes: 1 addition & 1 deletion tests/ShortestPath/BreadthFirstTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ public function testGetEdgesToThrowsOutOfBoundsIfVerticesArentConnected(): void
*
* @return void
*/
public function testGetEdgesIsEdgeCollection(): void
public function testGetEdgesIsArray(): void
{
$graph = new Graph;
$vertex_a = new Vertex($graph);
Expand Down
16 changes: 6 additions & 10 deletions tests/ShortestPath/MooreBellmanFordTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -403,17 +403,13 @@ public function testGetEdgesThrowsNegativeCycleException(): void
$vertex_c = new Vertex($graph);
$vertex_d = new Vertex($graph);
$vertex_e = new Vertex($graph);
$edge_a = $vertex_a->createEdgeTo($vertex_b);
$edge_b = $vertex_b->createEdgeTo($vertex_e);
$edge_c = $vertex_b->createEdgeTo($vertex_c);
$edge_d = $vertex_c->createEdgeTo($vertex_d);
$edge_e = $vertex_d->createEdgeTo($vertex_b);

$edge_a->setAttribute('weight', 2);
$edge_b->setAttribute('weight', 2);
$edge_c->setAttribute('weight', -2);
$edge_d->setAttribute('weight', 2);
$edge_e->setAttribute('weight', -2);
$vertex_a->createEdgeTo($vertex_b, ['weight' => 2]);
$vertex_b->createEdgeTo($vertex_e, ['weight' => 2]);
$vertex_b->createEdgeTo($vertex_c, ['weight' => -2]);
$vertex_b->createEdgeTo($vertex_c, ['weight' => -3]);
$vertex_c->createEdgeTo($vertex_d, ['weight' => 2]);
$vertex_d->createEdgeTo($vertex_b, ['weight' => -2]);

$bf = new MooreBellmanFord($vertex_a);

Expand Down
36 changes: 32 additions & 4 deletions tests/TravelingSalesman/NearestNeighborTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ public function testInstantiation(): void
$this->assertInstanceOf(NearestNeighbor::class, new NearestNeighbor(new Graph));
}

/**
* @covers PHGraph\TravelingSalesman\NearestNeighbor::__construct
*
* @return void
*/
public function testInstantiationWithVertices(): void
{
$g = new Graph;
$g->newVertex();

$this->assertInstanceOf(NearestNeighbor::class, new NearestNeighbor($g));
}

/**
* @covers PHGraph\TravelingSalesman\NearestNeighbor::setStartVertex
*
Expand All @@ -40,7 +53,7 @@ public function testSetStartVertex(): void
$nearest_neighbor = new NearestNeighbor($graph);
$nearest_neighbor->setStartVertex($a);

$this->assertEquals(36, $nearest_neighbor->getEdges()->sumAttribute('weight'));
$this->assertEquals(36, $this->sumAttribute($nearest_neighbor->getEdges(), 'weight'));
}

/**
Expand Down Expand Up @@ -140,7 +153,7 @@ public function testSimpleGraph()

$nearest_neighbor = new NearestNeighbor($graph);

$this->assertEquals(5, $nearest_neighbor->getEdges()->count());
$this->assertCount(5, $nearest_neighbor->getEdges());
}

/**
Expand Down Expand Up @@ -187,7 +200,7 @@ public function testComplexGraph()
$nearest_neighbor = new NearestNeighbor($graph);
$nearest_neighbor->setStartVertex($g);

$this->assertEquals(51, $nearest_neighbor->getEdges()->sumAttribute('weight'));
$this->assertEquals(51, $this->sumAttribute($nearest_neighbor->getEdges(), 'weight'));
}

/**
Expand Down Expand Up @@ -247,6 +260,21 @@ public function testFindingCheapestPath()

$nearest_neighbor = new NearestNeighbor($graph);

$this->assertEquals(7, $nearest_neighbor->getEdges()->sumAttribute('weight'));
$this->assertEquals(7, $this->sumAttribute($nearest_neighbor->getEdges(), 'weight'));
}

/**
* Sum given attribute.
*
* @param \PHGraph\Edge[] $collection collection of attributable to sum
* @param string $attribute name of attribute to sum
*
* @return float
*/
public function sumAttribute(array $collection, string $attribute): float
{
return array_sum(array_map(function ($attributable) use ($attribute) {
return $attributable->getAttribute($attribute, 0);
}, $collection));
}
}

0 comments on commit 2d5d976

Please sign in to comment.