Remarks
The maximum flow problem is an optimization problem that involves finding the maximum flow from source to sink nodes through a network of edges, each with a specified maximum capacity.
The algorithm is an implementation of the preflow-push algorithm (also known as push-relabel algorithm) and is based on
- Mehlhorn, Naeher: LEDA: a platform for combinatorial and geometric computing, Cambridge University Press, 2000, pp. 443–488.
Other Flow Algorithms
yFiles for HTML supports another algorithm related to network flow:
- MinimumCostFlow – Solves a minimum-cost flow problem where a given flow should be routed as cheaply as possible through a graph
Examples
// prepare the maximum flow algorithm
const algorithm = new MaximumFlow({
sources,
sinks,
capacities,
})
// run the algorithm
const result = algorithm.run(graph)
// highlight the partitions and the cut edges
for (const node of result.sourcePartition) {
graph.setStyle(node, sourcePartitionStyle)
}
for (const node of result.sinkPartition) {
graph.setStyle(node, sinkPartitionStyle)
}
for (const edge of result.minimumCut) {
graph.setStyle(edge, cutEdgeStyle)
}
// add labels indicating the actual flow
for (const edge of graph.edges) {
graph.addLabel(edge, String(result.flow.get(edge)))
}See Also
Developer's Guide
API
- maximumFlow
Members
Constructors
Properties
Gets or sets a mapping for capacities of edges.
0x7FFFFFFF as an edge's capacity signifies an infinite capacity for that edge.Gets or sets a collection of sink nodes.
See Also
Developer's Guide
Gets or sets a collection of source nodes.
See Also
Developer's Guide
Gets or sets the collection of edges which define a subset of the graph for the algorithms to work on.
If nothing is set, all edges of the graph will be processed.
If only the ItemCollection<TItem>.excludes are set, all edges in the graph except those provided in the ItemCollection<TItem>.excludes are processed.
Note that edges which start or end at nodes which are not in the subgraphNodes are automatically not considered by the algorithm.
ItemCollection<T> instances may be shared among algorithm instances and will be (re-)evaluated upon (re-)execution of the algorithm.
Examples
// prepare the maximum flow algorithm
const algorithm = new MaximumFlow({
sources,
sinks,
capacities,
// Ignore edges without target arrow heads
subgraphEdges: {
excludes: (edge: IEdge): boolean =>
edge.style instanceof PolylineEdgeStyle &&
edge.style.targetArrow instanceof Arrow &&
edge.style.targetArrow.type === ArrowType.NONE,
},
})
// run the algorithm
const result = algorithm.run(graph)
// highlight the partitions and the cut edges
for (const node of result.sourcePartition) {
graph.setStyle(node, sourcePartitionStyle)
}
for (const node of result.sinkPartition) {
graph.setStyle(node, sinkPartitionStyle)
}
for (const edge of result.minimumCut) {
graph.setStyle(edge, cutEdgeStyle)
}
// add labels indicating the actual flow
for (const edge of graph.edges) {
graph.addLabel(edge, String(result.flow.get(edge)))
}Gets or sets the collection of nodes which define a subset of the graph for the algorithms to work on.
If nothing is set, all nodes of the graph will be processed.
If only the ItemCollection<TItem>.excludes are set, all nodes in the graph except those provided in the ItemCollection<TItem>.excludes are processed.
ItemCollection<T> instances may be shared among algorithm instances and will be (re-)evaluated upon (re-)execution of the algorithm.
Examples
// prepare the maximum flow algorithm
const algorithm = new MaximumFlow({
sources,
sinks,
capacities,
subgraphNodes: {
// only consider elliptical nodes in the graph
includes: (node: INode): boolean =>
node.style instanceof ShapeNodeStyle &&
node.style.shape === ShapeNodeShape.ELLIPSE,
// but ignore the first node, regardless of its shape
excludes: graph.nodes.first()!,
},
})
// run the algorithm
const result = algorithm.run(graph)
// highlight the partitions and the cut edges
for (const node of result.sourcePartition) {
graph.setStyle(node, sourcePartitionStyle)
}
for (const node of result.sinkPartition) {
graph.setStyle(node, sinkPartitionStyle)
}
for (const edge of result.minimumCut) {
graph.setStyle(edge, cutEdgeStyle)
}
// add labels indicating the actual flow
for (const edge of graph.edges) {
graph.addLabel(edge, String(result.flow.get(edge)))
}Methods
Solves a maximum flow problem.
Parameters
- graph: IGraph
- The input graph to run the algorithm on.
Return Value
- MaximumFlowResult
- A MaximumFlowResult containing the computed flows as well as a cut between sources and sinks.
Throws
- Exception ({ name: 'InvalidOperationError' })
- If the algorithm can't create a valid result due to an invalid graph structure or wrongly configured properties.