PHPackages                             dbeurive/graph - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. dbeurive/graph

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

dbeurive/graph
==============

This package contains the implementation of various graphs' algorithms

1.0.3(9y ago)026Common Attribution-NonCommercial 4.0 International licensePHP

Since Dec 28Pushed 9y ago1 watchersCompare

[ Source](https://github.com/dbeurive/graph)[ Packagist](https://packagist.org/packages/dbeurive/graph)[ RSS](/packages/dbeurive-graph/feed)WikiDiscussions master Synced 2mo ago

READMEChangelogDependencies (1)Versions (4)Used By (0)

- [Introduction](#a0)
- [License](#a1)
- [Installation](#a2)
- [Graphs' types](#a3)
- [Graphs' representations](#a4)
    - [Directed graphs](#a5)
        - [Directed and unweighted](#a6)
        - [Directed and weighted](#a7)
    - [Undirected graphs](#a8)
        - [Undirected and unweighted](#a9)
        - [Undirected and weighted](#a10)
- [Graphs' API](#a11)
    - [Introduction](#a12)
    - [Loading a graph from a CSV file](#a13)
        - [Loading CSV with the default loader](#a14)
        - [Loading CSV with a customized loader](#a15)
    - [Dumping a graph into a CSV file](#a16)
        - [Dumping into CSV with the default dumper](#a17)
        - [Dumping into CSV with a customized dumper](#a18)
    - [Dumping a graph into its GraphViz representation](#a19)
- [Using the algorithms](#a20)
    - [The "Breadth First Search" algorithm](#a21)
        - [Synopsis](#a22)
    - [The "Depth First Search" algorithm](#a23)
        - [Synopsis](#a24)
    - [The Dijkstra's algorithm](#a25)
        - [Synopsis](#a26)
        - [Illustration](#a27)
    - [The Tarjan's algorithm](#a28)
        - [Synopsis](#a29)
        - [Illustration](#a30)

Introduction
==========================================

[](#introduction)

This repository contains the implementations of various algorithms for graphs.

- The [breadth-first search algorithm](https://en.wikipedia.org/wiki/Breadth-first_search)
- The [depth-first search algorithm](https://en.wikipedia.org/wiki/Depth-first_search)
- The [Dijkstra's algorithm](https://en.wikipedia.org/wiki/Dijkstra's_algorithm)
- The [Tarjan's strongly connected components algorithm](https://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm)

License
=====================================

[](#license)

This code is published under the following license:

[Creative Common Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)](https://creativecommons.org/licenses/by-nc/4.0/legalcode)

See the file [LICENSE.TXT](LICENSE.TXT)

Installation
==========================================

[](#installation)

From the command line:

```
composer require dbeurive/graph

```

Or, from within the file `composer.json`:

```
"require": {
    "dbeurive/graph": "*"
}

```

Graphs' types
===========================================

[](#graphs-types)

Graphs may be:

- Directed or not.
- Weighted or not.

A given graph may be:

Type of graphClassDirected and unweighted`\dbeurive\Graph\lists\DirectedUnweighted`Directed and weighted`\dbeurive\Graph\lists\DirectedWeighted`Undirected and unweighted`\dbeurive\Graph\lists\UndirectedUnweighted`Undirected and weighted`\dbeurive\Graph\lists\UndirectedWeighted`Graphs' representations
=====================================================

[](#graphs-representations)

Many formalisms may be used to represent a graph. For example:

- Edge lists
- Adjacency matrices
- Adjacency lists

> This document presents various ways used to represent graphs:
>
>

This PHP module uses the formalism known as "Adjacency lists".

Directed graphs
---------------------------------------------

[](#directed-graphs)

Vertices have **successors** (and **predecessors**).

We can choose to describe the graph through its lists of successors or through its lists of predecessors.

### Directed and unweighted

[](#directed-and-unweighted)

Let's consider the following directed unweighted graph:

[![Directed and unweighted](doc/images/directed-unweighted-1.gif "Directed and unweighted")](doc/images/directed-unweighted-1.gif)

The agency lists can be represented by the associative array below:

```
array(
    'vertex1' => array('vertex2' => null, 'vertex5' => null),
    'vertex5' => array('vertex6' => null, 'vertex7' => null),
    'vertex2' => array('vertex3' => null),
    'vertex3' => array('vertex4' => null),
    'vertex4' => array('vertex2' => null)
)
```

Or by a CSV file:

```
vertex1 vertex2 vertex5
vertex5 vertex6 vertex7
vertex2 vertex3
vertex3 vertex4
vertex4 vertex2

```

- The vertex `vertex1` has two successors: `vertex2` and `vertex5`.
- The vertex `vertex2` has one successor: `vertex3`.
- ...

See [this example](examples/directed-unweighted-in-memory.php).

### Directed and weighted

[](#directed-and-weighted)

Let's consider the following directed weighted graph:

[![Directed and weighted](doc/images/directed-weighted-1.gif "Directed and weighted")](doc/images/directed-weighted-1.gif)

The agency lists can be represented by the associative array below:

```
array(
    'vertex1' => array('vertex2' => 1, 'vertex5' => 2),
    'vertex5' => array('vertex6' => 3, 'vertex7' => 4),
    'vertex2' => array('vertex3' => 5),
    'vertex3' => array('vertex4' => 6),
    'vertex4' => array('vertex2' => 7)
)
```

Or by a CSV file:

```
vertex1 vertex2:1 vertex5:2
vertex5 vertex6:3 vertex7:4
vertex2 vertex3:5
vertex3 vertex4:6
vertex4 vertex2:7

```

- The vertex `vertex1` has two successors: `vertex2` and `vertex5`.
    - The weight associated to the edge from `vertex1` to `vertex2` is 1.
    - The weight associated to the edge from `vertex1` to `vertex5` is 2.
- The vertex `vertex2` has one successor: `vertex3`.
    - The weight associated to the edge from `vertex2` to `vertex3` is 5.
- ...

See [this example](examples/directed-weighted-in-memory.php).

Undirected graphs
-----------------------------------------------

[](#undirected-graphs)

Vertices have **neighbours**.

### Undirected and unweighted

[](#undirected-and-unweighted)

Let's consider the following undirected unweighted graph:

[![Undirected and unweighted](doc/images/undirected-unweighted-1.gif "Undirected and unweighted")](doc/images/undirected-unweighted-1.gif)

The agency lists can be represented by the associative array below:

```
array(
    'vertex1' => array('vertex2' => null, 'vertex5' => null),
    'vertex5' => array('vertex6' => null, 'vertex7' => null),
    'vertex2' => array('vertex3' => null),
    'vertex3' => array('vertex4' => null),
    'vertex4' => array('vertex2' => null)
);
```

Or by the CV file:

```
vertex1 vertex2 vertex5
vertex5 vertex6 vertex7
vertex2 vertex3
vertex3 vertex4
vertex4 vertex2

```

- The vertex `vertex1` has two neighbours: `vertex2` and `vertex5`.
- The vertex `vertex1` has two neighbours: `vertex6` and `vertex7`.
- ...

See [this example](examples/undirected-unweighted-in-memory.php).

### Undirected and weighted

[](#undirected-and-weighted)

Let's consider the following undirected weighted graph:

[![Undirected and weighted](doc/images/undirected-weighted-1.gif "Undirected and weighted")](doc/images/undirected-weighted-1.gif)

The agency lists can be represented by the associative array below:

```
array(
    'vertex1' => array('vertex2' => 1, 'vertex5' => 2),
    'vertex5' => array('vertex6' => 3, 'vertex7' => 4),
    'vertex2' => array('vertex3' => 5),
    'vertex3' => array('vertex4' => 6),
    'vertex4' => array('vertex2' => 7)
);
```

Or by the CSV file:

```
vertex1 vertex2:1 vertex5:2
vertex5 vertex6:3 vertex7:4
vertex2 vertex3:5
vertex3 vertex4:6
vertex4 vertex2:7

```

- The vertex `vertex1` has two successors: `vertex2` and `vertex5`.
    - The weight associated to the edge from `vertex1` to `vertex2` is 1.
    - The weight associated to the edge from `vertex1` to `vertex5` is 2.
- The vertex `vertex2` has one successor: `vertex3`.
    - The weight associated to the edge from `vertex2` to `vertex3` is 5.
- ...

See [this example](examples/undirected-weighted-in-memory.php).

Graphs' API
==========================================

[](#graphs-api)

Introduction
-------------------------------------------

[](#introduction-1)

The graph's API allows the following actions:

- Load a graph from a CSV file.
- Dump a graph into a CSV file.
- Create the [GraphViz](http://www.graphviz.org/) representation of a graph.
- "Complete" a graph's representation.
- For directed graphs: calculate the lists of predecessors from the lists of successors and vice versa.

Instead of presenting an-in depth description of the API, we will show examples of uses.

> Detailed API description can be generated using [phpDocumentor](https://www.phpdoc.org/). Just go to the root directory of this package and issue the following command: `phpdoc`. The documentation will be generated within the directory `doc/api`.

Loading a graph from a CSV file
--------------------------------------------------------------

[](#loading-a-graph-from-a-csv-file)

### Loading CSV with the default loader

[](#loading-csv-with-the-default-loader)

Synopsis:

```
$graph = new DirectedUnweighted(); // or DirectedWeighted
$graph->loadSuccessorsFromCsv($csvSuccessorsPath);
$graph->loadPredecessorsFromCsv($csvPredecessorsPath);

$graph = new UndirectedUnweighted(); // or UndirectedWeighted
$graph->loadNeighboursFromCsv($csvSuccessorsPath);
```

By default:

- Fields are separated by a space.
- Edges' weight is indicated by the character ':'.
- Vertices' names are loaded "as is".

Examples of standard CSV files:

```
vertex1
vertex2 vertex1 vertex4
vertex5 vertex1
vertex6 vertex5
vertex7 vertex5
vertex3 vertex2
vertex4 vertex3

```

or:

```
vertex1
vertex2 vertex1:1 vertex4:7
vertex5 vertex1:2
vertex6 vertex5:3
vertex7 vertex5:4
vertex3 vertex2:5
vertex4 vertex3:6

```

See example [from-csv-directed-unweighted.php](examples/from-csv-directed-unweighted.php).

See example [from-csv-directed-weighted.php](examples/from-csv-directed-weighted.php).

See example [from-csv-undirected-unweighted.php](examples/from-csv-undirected-unweighted.php).

See example [from-csv-undirected-weighted.php](examples/from-csv-undirected-weighted.php).

### Loading CSV with a customized loader

[](#loading-csv-with-a-customized-loader)

Synopsis:

```
$graph = new DirectedUnweighted(); // or UndirectedUnweighted
$graph->setFieldSeparator(';');
$graph->setVertexUnserializer(function($inVertex) { return strtoupper($inVertex); });
$graph->setLinePreProcessor(function($inLine) { return trim($inLine); });

$graph = new DirectedWeighted(); // or UndirectedWeighted
$graph->setFieldSeparator(';');
$graph->setVertexUnserializer(function($inVertex) { return strtoupper($inVertex); });
$graph->setLinePreProcessor(function($inLine) { return trim($inLine); });
$graph->setWeightIndicator('::');
```

While loading CSV files, it is possible to specify non-standard attributes:

- The field separator. The default field separator is the space (" ").
- The weight indicator (for weighted graphs only). The default weight indicator is the character ":".

It is also possible to specify actions applied to the following data:

- The vertices' names.
- The line of CSV (for example, you can remove leading and trailing spaces).

> Actions are specified via a "callable" (see [this explanation](http://php.net/manual/en/language.types.callable.php)).

In the following examples:

- We changed the field separator (we use ";" instead of " ").
- We changed the weight indicator (we used "::" instead of ":").
- We convert vertices' names into uppercase.
- We remove leading and trailing spaces from each line before any other process.

See example [from-csv-directed-unweighted-non-standard.php](examples/from-csv-directed-unweighted-non-standard.php).

See example [from-csv-directed-weighted-non-standard.php](examples/from-csv-directed-weighted-non-standard.php).

Dumping a graph into a CSV file
--------------------------------------------------------------

[](#dumping-a-graph-into-a-csv-file)

### Dumping into CSV with the default dumper

[](#dumping-into-csv-with-the-default-dumper)

Synopsis:

```
$graph = new DirectedUnweighted();        // Or DirectedWeighted
$graph->setSuccessors($listOfSuccessors); // You can also set the lists of predecessors.
$graph->dumpSuccessorsToCsv($csvPath);    // You can also dump the lists of predecessors.

$graph = new UndirectedUnweighted();      // Or UndirectedWeighted
$graph->setNeighbours($listOfNeighbours);
$graph->dumpNeighboursToCsv($csvPath);
```

See example [to-csv-directed-unweighted.php](examples/to-csv-directed-unweighted.php).

See example [to-csv-directed-weighted.php](examples/to-csv-directed-weighted.php).

See example [to-csv-undirected-unweighted.php](examples/to-csv-undirected-unweighted.php).

See example [to-csv-undirected-weighted.php](examples/to-csv-undirected-weighted.php).

### Dumping into CSV with a customized dumper

[](#dumping-into-csv-with-a-customized-dumper)

Synopsis:

```
// Directed Weighted

$graph = new DirectedWeighted();
$graph->setSuccessors($listOfSuccessors);
$graph->calculatePredecessorsFromSuccessors();
$graph->setFieldSeparator(';');
$graph->setVertexSerializer(function($inVertex) { return strtoupper($inVertex); });
$graph->setWeightIndicator('::');
$graph->dumpSuccessorsToCsv($csvPath);
$graph->dumpPredecessorsToCsv($csvPath);

// Directed Unweighted

$graph = new DirectedUnweighted();
$graph->setSuccessors($listOfSuccessors);
$graph->calculatePredecessorsFromSuccessors();
$graph->setFieldSeparator(';');
$graph->setVertexSerializer(function($inVertex) { return strtoupper($inVertex); });
$graph->dumpSuccessorsToCsv($csvPath);
$graph->dumpPredecessorsToCsv($csvPath);

// Undirected Weighted

$graph = new UndirectedWeighted();
$graph->setFieldSeparator(';');
$graph->setWeightIndicator('::');
$graph->setVertexSerializer(function ($inVertex) { return strtoupper($inVertex); } );
$graph->setNeighbours($listOfNeighbours);
$graph->dumpNeighboursToCsv($csvPath);

// Undirected Unweighted

$graph = new UndirectedUnweighted();
$graph->setFieldSeparator(';');
$graph->setVertexSerializer(function ($inVertex) { return strtoupper($inVertex); } );
$graph->setNeighbours($listOfNeighbours);
$graph->dumpNeighboursToCsv($csvPath);
```

While dumping CSV files, it is possible to specify non-standard attributes:

- The field separator. The default field separator is the space (" ").
- The weight indicator (for weighted graphs only). The default weight indicator is the character ":".

It is also possible to specify actions applied to the following data:

- The vertices' names.

> Actions are specified via a "callable" (see [this explanation](http://php.net/manual/en/language.types.callable.php)).

See example [to-csv-directed-unweighted-non-standard.php](examples/to-csv-directed-unweighted-non-standard.php).

See example [to-csv-directed-weighted-non-standard.php](examples/to-csv-directed-weighted-non-standard.php).

See example [to-csv-undirected-unweighted-non-standard.php](examples/to-csv-undirected-unweighted-non-standard.php).

See example [to-csv-undirected-weighted-non-standard.php](examples/to-csv-undirected-weighted-non-standard.php).

Dumping a graph into its GraphViz representation
-------------------------------------------------------------------------------

[](#dumping-a-graph-into-its-graphviz-representation)

Synopsis:

```
$graph = new DirectedUnweighted(); // or DirectedWeighted
$graph->setSuccessors($listOfSuccessors);
$txt = $graph->dumpSuccessorsToGraphviz();
$graph->calculatePredecessorsFromSuccessors();
$txt = $graph->dumpPredecessorsToGraphviz();

$graph = new UndirectedUnweighted(); // or UndirectedWeighted
$graph->setNeighbours($listOfNeighbours);
$txt = $graph->dumpNeighboursToGraphviz();
```

> Please note that the generated GraphViz representation is highly customisable. The methods `dumpSuccessorsToGraphviz`, `dumpPredecessorsToGraphviz` and `dumpNeighboursToGraphviz` take parameters. These parameters allow you to customise the appearances of the vertices and of the edges.

See example [to-graphviz-directed-unweighted.php](examples/to-graphviz-directed-unweighted.php).

See example [to-graphviz-directed-weighted.php](examples/to-graphviz-directed-weighted.php).

See example [to-graphviz-undirected-unweighted.php](examples/to-graphviz-undirected-unweighted.php).

See example [to-graphviz-undirected-weighted.php](examples/to-graphviz-undirected-weighted.php).

Using the algorithms
===================================================

[](#using-the-algorithms)

The "Breadth First Search" algorithm
-------------------------------------------------------------------

[](#the-breadth-first-search-algorithm)

See the description [here](https://en.wikipedia.org/wiki/Breadth-first_search).

### Synopsis

[](#synopsis)

```
$vertices = array();

// Define a callback that will be executed for each visited vertex.
// * If the function returns true, then the exploration of the graph continues.
// * If the function returns false, then the exploration of the graph ends.

$callback = function($inVertex) use(&$vertices) {
    $vertices[] = $inVertex;
    return true;
};

// For directed graphs

$graph = new DirectedUnweighted(); // or DirectedWeighted
$graph->setSuccessors($successors, true);
$graph->calculatePredecessorsFromSuccessors();
$algo = new DirectedBreadthFirstSearch($graph, $callback);
$algo->followSuccessors();
$algo->run('e1', $callback); // Start traversing the graph from the vertex 'e1', following the sucessors.
$algo->followPredecessors();
$algo->run('e1', $callback); // Start traversing the graph from the vertex 'e1', following the predecessors.

// For undirected graphs

$graph = new UndirectedUnweighted(); // or UndirectedWeighted
$graph->setNeighbours($successors, true);
$algorithm = new UndirectedBreadthFirstSearch($graph, $callback);
$algorithm->run('e1', $callback); // Start traversing the graph.
```

> Please note that this algorithm works for directed **and undirected** graphs.

> Please note that the returned value of the callback function (`$callback`) determines the behaviour of the method `run()`.
>
> - If the callback function returns the value true, then the method `run()` continues the traversal of the graph.
> - If the callback function returns the value false, then the method `run()` stops the traversal of the graph.

See example [breadth-first-search-directed.php](examples/breadth-first-search-directed.php).

See example [breadth-first-search-undirected.php](examples/breadth-first-search-undirected.php).

The "Depth First Search" algorithm
-----------------------------------------------------------------

[](#the-depth-first-search-algorithm)

See the description [here](https://en.wikipedia.org/wiki/Depth-first_search).

### Synopsis

[](#synopsis-1)

```
$vertices = array();

// Define a callback that will be executed for each visited vertex.
// * If the function returns true, then the exploration of the graph continues.
// * If the function returns false, then the exploration of the graph ends.

$callback = function($inVertex) use(&$vertices) {
    $vertices[] = $inVertex;
    return true;
};

// For directed graphs

$graph = new DirectedUnweighted(); // Or DirectedWeighted
$graph->setSuccessors($successors, true);
$graph->calculatePredecessorsFromSuccessors();
$algo = new DirectedDepthFirstSearch($graph, $callback);
$algo->followSuccessors();
$algo->run('e1', $callback); // Start traversing the graph from the vertex 'e1', following the successors.
$algo->followPredecessors();
$algo->run('e1', $callback); // Start traversing the graph from the vertex 'e1', following the predecessors.
```

> Please note that this algorithm works for directed **and undirected** graphs.

> Please note that the returned value of the callback function (`$callback`) determines the behaviour of the method `run()`.
>
> - If the callback function returns the value true, then the method `run()` continues the traversal of the graph.
> - If the callback function returns the value false, then the method `run()` stops the traversal of the graph.

See example [depth-first-search-directed.php](examples/depth-first-search-directed.php).

See example [depth-first-search-undirected.php](examples/depth-first-search-undirected.php).

The Dijkstra's algorithm
-------------------------------------------------------

[](#the-dijkstras-algorithm)

See the description [here](https://en.wikipedia.org/wiki/Dijkstra's_algorithm).

- This algorithm works for both directed and undirected graphs.
- The graph must be weighted.

### Synopsis

[](#synopsis-2)

```
// With directed graphs

$graph = new DirectedWeighted();
$graph->setSuccessors($successors, true);
$algorithm = new DirectedDijkstra($graph);
$algorithm->followSuccessors();
$distances = $algorithm->run($vertexName); // Start the algorithm.
$txt = $algorithm->dumpToGraphviz(); // For a nice representation of the result.

// With undirected graphs

$graph = new UndirectedWeighted();
$graph->setNeighbours($neighbours, true);
$algorithm = new UndirectedDijkstra($graph);
$distances = $algorithm->run($vertexName);
$txt = $algorithm->dumpToGraphviz(); // For a nice representation of the result.
```

See example [dijkstra-directed.php](examples/dijkstra-directed.php).

See example [dijkstra-undirected.php](examples/dijkstra-undirected.php).

### Illustration

[](#illustration)

Given the graph below, let's find the shortest paths from the vertex "`1`" to all other vertices.

[![Directed and weighted](doc/images/DirectedDijkstraTest-Input.gif "Directed and weighted")](doc/images/DirectedDijkstraTest-Input.gif)

After running the algorithm, we get:

[![Directed and weighted](doc/images/DirectedDijkstraTest-Result.gif "Directed and weighted")](doc/images/DirectedDijkstraTest-Result.gif)

- The shortest distance between vertex "`1`" and vertex "`3`" is 9.
- The shortest distance between vertex "`1`" and vertex "`6`" is 11.
- The shortest distance between vertex "`1`" and vertex "`5`" is 20.
- ...

Shortest paths are printed in red.

The Tarjan's algorithm
-----------------------------------------------------

[](#the-tarjans-algorithm)

See the description [here](https://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm).

- This algorithm works for both directed graphs only.
- The graph may be weighted or not.

### Synopsis

[](#synopsis-3)

```
$graph = new DirectedUnweighted(); // or DirectedWeighted
$graph->setSuccessors($successors, true);

$algorithm = new DirectedTarjan($graph);
$algorithm->followSuccessors();
$scc = $algorithm->run();
$cycles = $algorithm->getCycles();
$txt = $algorithm->dumpToGraphviz(); // For a nice representation of the result.
```

See example [tarjan.php](examples/tarjan.php).

### Illustration

[](#illustration-1)

Given the graph below, let's find all the cycles:

[![Directed](doc/images/DirectedTarjanTest-Input.gif "Directed")](doc/images/DirectedTarjanTest-Input.gif)

After running the algorithm, we get:

[![Directed](doc/images/DirectedTarjanTest-Output.gif "Directed")](doc/images/DirectedTarjanTest-Output.gif)

> Please note that this algorithm does not return the list of cycles within the graph. It returns the list of *strongly connected components*. However, cycle detection is an application of this algorithm. Here, we choose to show the result of the method `getCycles()`.

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity6

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity65

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~5 days

Total

3

Last Release

3415d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/18211524?v=4)[Denis BEURIVE](/maintainers/dbeurive)[@dbeurive](https://github.com/dbeurive)

---

Top Contributors

[![dbeurive](https://avatars.githubusercontent.com/u/18211524?v=4)](https://github.com/dbeurive "dbeurive (7 commits)")

---

Tags

AlgorithmgraphdijkstraDepth First SearchTarjanBreadth First Search

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/dbeurive-graph/health.svg)

```
[![Health](https://phpackages.com/badges/dbeurive-graph/health.svg)](https://phpackages.com/packages/dbeurive-graph)
```

###  Alternatives

[novus/nvd3

A reusable charting library written in d3.js

7.2k207.7k2](/packages/novus-nvd3)[rubix/ml

A high-level machine learning and deep learning library for the PHP language.

2.2k1.4M28](/packages/rubix-ml)[graphp/graph

GraPHP is the mathematical graph/network library written in PHP.

711292.6k3](/packages/graphp-graph)[donatello-za/rake-php-plus

Yet another PHP implementation of the Rapid Automatic Keyword Extraction algorithm (RAKE).

271865.1k10](/packages/donatello-za-rake-php-plus)[graphp/algorithms

Common mathematical graph algorithms implemented in PHP

1402.9M14](/packages/graphp-algorithms)[amenadiel/jpgraph

Composer Friendly, full refactor of JpGraph, library to make graphs and charts

1492.2M7](/packages/amenadiel-jpgraph)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
