Releases: graphp/graph
Releases · graphp/graph
v0.9.3
v0.9.2
v0.9.1
-
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\Testsnamespace,
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)
v0.9.0
- BC break: Split off individual components in order to stabilize core graph lib.
(#120) - Split off
Algorithmnamespace into separate graphp/algorithms package.
(#119) - Split off
Exporter\TrivialGraphFormatinto separate graphp/trivial-graph-format package.
(#121) - Split off
Loadernamespace into separate graphp/plaintext package.
(#117) - BC break: Remove Exporter from
GraphandGraph::__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)
v0.8.0
- 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,VertexandEdgeBaseclasses can now be
extended in order to implement a custom behavior. As such, one can now also
instantiate them using the normalnewoperator instead of having to use
Graph::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()and
Algorithm\Directed::isMixed()in order to complement the renamed
Algorithm\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 an
InvalidArgumentExceptioninstead (#87) - Feature: Support loop
Walks, 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\MooreBellmanFordnow also works for unweighted
edges. This also fixes an issue whereAlgorithm\DetectNegativeCycledidn't work
for unweighted edges. (#81) - Fix: The
Algorithm\MinimumCostFlowalgorithms 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() |
v0.7.1
v0.7.0
- Feature: Add new
Set\VerticesandSet\Edgesclasses that handle common
operations on a Set of multipleVertexandEdgeinstances 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 eachSetimplements 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 anSetis empty,
you now have to use the more explicit syntax$set->isEmpty(). - BC break:
Vertex::getVertices(),Vertex::getVerticesEdgeTo()and
Vertex::getVerticesEdgeFrom()now return aSet\Verticesinstance 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 / distinctVertexinstances, use
Vertex::getVertices()->getVerticesDistinct()where applicable. - BC break: Remove all occurances of
getVerticesId(), use
getVertices()->getIds()instead. - BC break: Merge
CycleintoWalk(#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 methods
Algorithm\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 returnedWalkinstance is actually a valid Cycle,
i.e. the startVertexis the same as the endVertex(#61) - BC break: Each
Algorithm\ShortestPathalgorithm 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\ShortestPathalgorithm now consistently throws an
OutOfBoundsExceptionfor 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), adjustAlgorithm\Tree\Base::isTree()
accordingly.
(#72) - BC break: Remove all occurances of
getNumberOfVertices()and
getNumberOfEdges()(#75 and
#48):
| Old name | New name |
|---|---|
$set->getNumberOfVertices() |
count($set->getVertices()) |
$set->getNumberOfEdges() |
count($set->getEdges()) |
- BC break: Replace base
Setclass withSet\DualAggregateinterface. 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\MinimumSpanningTreealgorithm now supports
undirected and mixed Graphs, as well as null weights for Edges.
(#73) - BC break: Each
Algorithm\MinimumSpanningTreealgorithm now throws an
UnexpectedValueExceptionfor 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 rightUnderflowExceptionif no cycle was found
(#62) - Fix: Calling
Exporter\Image::setFormat()had no effect due to misassignment
(#70 @fgm)
v0.6.0
- 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\UmlClassDiagramto separate fhaculty/graph-uml
repo (#38) - BC break: Remove needless
Algorithm\MinimumSpanningTree\PrimWithIf
(useAlgorithm\MinimumSpanningTree\Priminstead)
(#45) - BC break:
Vertex::createEdgeTo()now returns an instance of type
Edge\Undirectedinstead ofEdge\UndirectedId
(#46) - BC break:
Edge\Base::setCapacity()now consistently throws anRangeException
instead ofInvalidArgumentExceptionif the current flow exceeds the new maximum
capacity (#53) - Feature: New
Algorithm\Treenamespace 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): - New
Algorithm\Weight(#33) - New
Algorithm\Degree(#29, #49) - New
Algorithm\Directed(#34) - New
Algorithm\Symmetric(#41) - New
Algorithm\Complete(#43) - New
Algorithm\Flow(#30, #47) - New
Algorithm\Tree(#44) - New
Algorithm\Loop(#51) - New
Algorithm\Parallel(#52) - New
Algorithm\Property(#54) - 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/Edgelayout attributes
(#32) - Fix: Getting multiple parallel edges for undirected edges
(#52)