-
Feature: Support PHP 8.1 release. (#208 by @clue)
-
Fix: Fix automatic vertex ID generation when using vertex IDs with strings. (#204 by @viktorprogger)
-
Improve test suite and use GitHub Actions for continuous integration (CI). (#207 by @clue)
- Feature: Support PHP 8 and PHPUnit 9.3. (#200 by @SimonFrings)
-
Fix: Deleting vertex with loop edge no longer fails. (#149 by @tomzx)
-
Fix: Fix returning directed loop edges and adjacent vertices from vertex twice. (#170 by @clue)
-
Minor documentation updates and fixes. (#153 by @marclaporte and #163, #164 and #172 by @clue)
-
Improve test suite to move tests to
Fhaculty\Graph\Tests
namespace, update test suite to support PHPUnit 6 and PHPUnit 5 and support running on legacy PHP 5.3 through PHP 7.2 and HHVM. (#148 by @tomzx and #150 and #162 by @clue) -
Originally planned to add a new
AttributeAware::removeAttribute()
method, but reverted due to BC break. Change will be reconsidered for next major release. (#138 and #171 by @johnathanmdell and @clue)
-
BC break: Split off individual components in order to stabilize core graph lib. (#120)
-
Split off
Algorithm
namespace into separate graphp/algorithms package. (#119) -
Split off
Exporter\TrivialGraphFormat
into separate graphp/trivial-graph-format package. (#121) -
Split off
Loader
namespace into separate graphp/plaintext package. (#117)
-
-
BC break: Remove Exporter from
Graph
andGraph::__toString()
(trivial graph format exporter has been split off). (#122) -
BC break: Vertices can no longer be sorted by (in/out)degree (degree algorithm has been split off). (#128)
-
Apply PSR-4 layout under
src/
and add tests to achieve 100% test coverage. (#127 & #129)
-
Feature: Add general purpose Attributes. (#103)
-
BC break: Split off all GraphViz-related classes to a separate graphp/graphviz package. (#115)
-
Feature: The base
Graph
,Vertex
andEdgeBase
classes can now be extended in order to implement a custom behavior. As such, one can now also instantiate them using the normalnew
operator instead of having to useGraph::createVertex()
family of methods. (#82) -
BC break: Rename
Algorithm\Directed::isDirected()
to remove its ambiguity in regards to mixed and/or empty graphs (#80)Old name New name Algorithm\Directed::isDirected()
Algorithm\Directed::hasDirected()
-
Feature: Add new
Algorithm\Directed::hasUndirected()
andAlgorithm\Directed::isMixed()
in order to complement the renamedAlgorithm\Directed::hasDirected()
(#80) -
BC break:
Walk::factoryCycleFromVertices()
no longer tries to auto-complete a cycle if the first vertex does not match the last one, but now throws anInvalidArgumentException
instead (#87) -
Feature: Support loop
Walk
s, i.e. a walk with only a single edge from vertex A back to A (#87) -
Fix: Stricter checks for invalid cycles, such as one with an invalid predecessor-map or no edges at all (#87)
-
Fix: The
Algorithm\ShortestPath\MooreBellmanFord
now also works for unweighted edges. This also fixes an issue whereAlgorithm\DetectNegativeCycle
didn't work for unweighted edges. (#81) -
Fix: The
Algorithm\MinimumCostFlow
algorithms now work again. The reference to a non-existant class has been updated. Also fixed several issues with regards to special cases such as disconnected or undirected graphs. (#74) -
BC break: Remove unneeded alias definitions of
getVertexFirst()
,getVertexSource()
andgetVertexTarget()
(#76):Old name New name Graph::getVertexFirst()
Graph::getVertices()->getVertexFirst()
Walk::getVertexSource()
Walk::getVertices()->getVertexFirst()
Walk::getVertexTarget()
Walk::getVertices()->getVertexLast()
-
Fix: Throwing an
UnexpectedValueException
if writing GraphViz Dot script to a temporary file fails and remove its debugging output (#77 and #78 @Metabor) -
Fix: Improved GraphViz support for MS Windows (#99)
-
Feature: Add new
Set\Vertices
andSet\Edges
classes that handle common operations on a Set of multipleVertex
andEdge
instances respectively. (#48) -
BC break: Move operations and their corresponding constants concerning Sets to their corresponding Sets:
Old name New name Edge\Base::getFirst()
Set\Edges::getEdgeOrder()
Edge\Base::getAll()
Set\Edges::getEdgesOrder()
Edge\Base::ORDER_*
Set\Edges::ORDER_*
--- --- Vertex::getFirst()
Set\Vertices::getVertexOrder()
Vertex::getAll()
Set\Vertices::getVerticesOrder()
Vertex::ORDER_
Set\Vertices::ORDER_*
-
BC break: Each
getVertices*()
andgetEdges*()
method now returns aSet
instead of a primitive array of instances. Most of the time this should work without changing your code, because eachSet
implements anIterator
interface and can easily be iterated usingforeach
. However, using aSet
instead of a plain array differs when checking its boolean value or comparing two Sets. I.e. if you happen to want to check if anSet
is empty, you now have to use the more explicit syntax$set->isEmpty()
. -
BC break:
Vertex::getVertices()
,Vertex::getVerticesEdgeTo()
andVertex::getVerticesEdgeFrom()
now return aSet\Vertices
instance that may contain duplicate vertices if parallel (multiple) edges exist. Previously there was no easy way to detect this situation - this is now the default. If you also want to get unique / distinctVertex
instances, useVertex::getVertices()->getVerticesDistinct()
where applicable. -
BC break: Remove all occurances of
getVerticesId()
, usegetVertices()->getIds()
instead. -
BC break: Merge
Cycle
intoWalk
(#61). As such, its static factory methods had to be renamed. Update your references if applicable:Old name New name Cycle::factoryFromPredecessorMap()
Walk::factoryCycleFromPredecessorMap()
Cycle::factoryFromVertices()
Walk::factoryCycleFromVertices()
Cycle::factoryFromEdges()
Walk::factoryCycleFromEdges()
-
BC break: Remove
Graph::isEmpty()
because it's not well-defined and might be confusing. Most literature suggests it should check for existing edges, whereas the old behavior was to check for existing vertices instead. Use either of the new and more transparent methodsAlgorithm\Property\GraphProperty::isNull()
(old behavior) or (where applicable)Algorithm\Property\GraphProperty::isEdgeless()
(#63). -
BC break: Each of the above methods (
Walk::factoryCycleFromPredecessorMap()
,Walk::factoryCycleFromVertices()
,Walk::factoryCycleFromEdges()
) now actually makes sure the returnedWalk
instance is actually a valid Cycle, i.e. the startVertex
is the same as the endVertex
(#61) -
BC break: Each
Algorithm\ShortestPath
algorithm now consistenly does not return a zero weight for the root Vertex and now supports loop edges on the root Vertex (#62) -
BC break: Each
Algorithm\ShortestPath
algorithm now consistently throws anOutOfBoundsException
for unreachable vertices (#62) -
BC break: A null Graph (a Graph with no Vertices and thus no Edges) is not a valid tree (because it is not connected), adjust
Algorithm\Tree\Base::isTree()
accordingly. (#72) -
BC break: Remove all occurances of
getNumberOfVertices()
andgetNumberOfEdges()
(#75 and #48):Old name New name $set->getNumberOfVertices()
count($set->getVertices())
$set->getNumberOfEdges()
count($set->getEdges())
-
BC break: Replace base
Set
class withSet\DualAggregate
interface. This is unlikely to affect you, but might potentially break your custom inheritance or polymorphism for algorithms. (#75) -
Feature: Add
Algorithm\ShortestPath\Base::hasVertex(Vertex $vertex)
to check whether a path to the given Vertex exists (#62). -
Feature: Support opening GraphViz images on Mac OS X in default image viewer (#67 @onigoetz)
-
Feature: Add
Algorithm\MinimumSpanningTree\Base::getWeight()
to get total weight of resulting minimum spanning tree (MST). (#73) -
Feature: Each
Algorithm\MinimumSpanningTree
algorithm now supports undirected and mixed Graphs, as well as null weights for Edges. (#73) -
BC break: Each
Algorithm\MinimumSpanningTree
algorithm now throws anUnexpectedValueException
for unconnected Graphs (and thus also null Graphs). (#73) -
Feature: Add
Walk::factoryFromVertices()
(#64). -
Fix: Checking
Walk::isValid()
(#61) -
Fix: Missing import prevented
Algorithm\ShortestPath\MooreBellmanFord::getCycleNegative()
from actually throwing the rightUnderflowException
if no cycle was found (#62) -
Fix: Calling
Exporter\Image::setFormat()
had no effect due to misassignment (#70 @FGM)
-
BC break: Move algorithm definitions in base classes to separate algorithm classes (#27). The following methods containing algorithms were now moved to separate algorithm classes. This change encourages code-reuse, simplifies spotting algorithms, helps reducing complexity, improves testablity and avoids tight coupling. Update your references if applicable:
Old name New name Related ticket Set::getWeight()
Algorithm\Weight::getWeight()
#33 Set::getWeightFlow()
Algorithm\Weight::getWeightFlow()
#33 Set::getWeightMin()
Algorithm\Weight::getWeightMin()
#33 Set::isWeighted()
Algorithm\Weight::isWeighted()
#33 - - - Graph::getDegree()
Algorithm\Degree::getDegree()
#29 Graph::getDegreeMin()
Algorithm\Degree::getDegreeMin()
#29 Graph::getDegreeMax()
Algorithm\Degree::getDegreeMax()
#29 Graph::isRegular()
Algorithm\Degree::isRegular()
#29 Graph::isBalanced()
Algorithm\Degree::isBalanced()
#29 Vertex::getDegree()
Algorithm\Degree:getDegreeVertex()
#49 Vertex::getDegreeIn()
Algorithm\Degree:getDegreeInVertex()
#49 Vertex::getDegreeOut()
Algorithm\Degree:getDegreeOutVertex()
#49 Vertex::isSink()
Algorithm\Degree:isVertexSink()
#49 Vertex::isSource()
Algorithm\Degree:isVertexSource()
#49 Vertex::isIsolated()
Algorithm\Degree::isVertexIsolated()
#49 - - - Set::isDirected()
Algorithm\Directed::isDirected()
#34 - - - Graph::isSymmetric()
Algorithm\Symmetric::isSymmetric()
#41 - - - Graph::isComplete()
Algorithm\Complete::isComplete()
#43 - - - Set::hasFlow()
Algorithm\Flow::hasFlow()
#47 Graph::getBalance()
Algorithm\Flow::getBalance()
#30, #47 Graph::isBalancedFlow()
Algorithm\Flow::isBalancedFlow()
#30, #47 Vertex::getFlow()
Algorithm\Flow::getFlowVertex()
#47 - - - Vertex::isLeaf()
Algorithm\Tree\Undirected::isVertexLeaf()
#44 - - - Set::hasLoop()
Algorithm\Loop::hasLoop()
#51 Vertex::hasLoop()
Algorithm\Loop::hasLoopVertex()
#51 - - - Set::hasEdgeParallel()
Algorithm\Parallel::hasEdgeParallel()
#52 Edge\Base::hasEdgeParallel()
Algorithm\Parallel::hasEdgeParallelEdge()
#52 Edge\Base::getEdgesParallel()
Algorithm\Parallel::getEdgeParallelEdge()
#52 - - - Graph::isEdgeless()
Algorithm\Property\GraphProperty::isEdgeless()
#54 Graph::isTrivial()
Algorithm\Property\GraphProperty::isTrivial()
#54 Walk::isCycle()
Algorithm\Property\WalkProperty::isCycle()
#54 Walk::isPath()
Algorithm\Property\WalkProperty::isPath()
#54 Walk::hasCycle()
Algorithm\Property\WalkProperty::hasCycle()
#54 Walk::isLoop()
Algorithm\Property\WalkProperty::isLoop()
#54 Walk::isDigon()
Algorithm\Property\WalkProperty::isDigon()
#54 Walk::isTriangle()
Algorithm\Property\WalkProperty::isTriangle()
#54 Walk::isSimple()
Algorithm\Property\WalkProperty::isSimple()
#54 Walk::isHamiltonian()
Algorithm\Property\WalkProperty::isHamiltonian()
#54 Walk::isEulerian()
Algorithm\Property\WalkProperty::isEulerian()
#54 -
BC break: Remove unneeded algorithm alias definitions (#31, #50). The following alias definitions have been removed, their original/actual name has already existed before and continues to work unchanged. Update your references if applicable:
Old/removed alias definition Actual name Graph::isConnected()
Algorithm\ConnectedComponents::isSingle()
Graph::hasEulerianCycle()
Algorithm\Eulerian::hasCycle()
Graph::getNumberOfComponents()
Algorithm\ConnectedComponents::getNumberOfComponents()
Graph::getNumberOfGroups()
Algorithm\Groups::getNumberOfGroups()
Graph::isBipartit()
Algorithm\Bipartit::isBipartit()
Vertex::hasPathTo()
Algorithm\ShortestPath\BreadthFirst::hasVertex()
Vertex::hasPathFrom()
Algorithm\ShortestPath\BreadthFirst::hasVertex()
Vertex::getVerticesPathTo()
Algorithm\ShortestPath\BreadthFirst::getVertices()
Vertex::getVerticesPathFrom()
Algorithm\ShortestPath\BreadthFirst::getVertices()
-
BC break:
Graph::createVertices()
now returns an array of vertices instead of the chainableGraph
(#19) -
BC break: Move
Loader\UmlClassDiagram
to separate fhaculty/graph-uml repo (#38) -
BC break: Remove needless
Algorithm\MinimumSpanningTree\PrimWithIf
(useAlgorithm\MinimumSpanningTree\Prim
instead) (#45) -
BC break:
Vertex::createEdgeTo()
now returns an instance of typeEdge\Undirected
instead ofEdge\UndirectedId
(#46) -
BC break:
Edge\Base::setCapacity()
now consistently throws anRangeException
instead ofInvalidArgumentException
if the current flow exceeds the new maximum capacity (#53) -
Feature: New
Algorithm\Tree
namespace with algorithms for undirected and directed, rooted trees (#44) -
Feature: According to be above list of moved algorithm methods, the following algorithm classes have been added (#27):
-
Feature:
Graph::createVertices()
now also accepts an array of vertex IDs (#19) -
Feature: Add
Algorithm\Property\WalkProperty::hasLoop()
alias definition for completeness (#54) -
Feature: Add
Algorithm\Property\WalkProperty::isCircuit()
definition to distinguish circuits from cycles (#54) -
Fix: Checking hamiltonian cycles always returned false (#54)
-
Fix: A Walk with no edges is no longer considered a valid cycle (#54)
-
Fix: Various issues with
Vertex
/Edge
layout attributes (#32) -
Fix: Getting multiple parallel edges for undirected edges (#52)
- First tagged release (See issue #20 for more info on why it starts as v0.5.0)