Class NetworkSimplex
- All Implemented Interfaces:
Algorithm,DynamicAlgorithm,org.graphstream.stream.AttributeSink,org.graphstream.stream.ElementSink,org.graphstream.stream.Sink
- Direct Known Subclasses:
DynamicOneToAllShortestPath
public class NetworkSimplex extends org.graphstream.stream.SinkAdapter implements DynamicAlgorithm
Minimum cost flow problem
Network simplex method is an algorithm that solves the minimum cost flow (MCF) problem for an oriented graph.
The MCF problem can be stated as follows. Each node has associated number supply representing the available supply of or demand for flow at that node. If supply is positive, the node is a supply node, if supply is negative, the node is a demand node and if supply is zero, the node is a transshipment node. Each arc has associated capacity (possibly infinite) and cost per unit flow. The MCF problem is to send the required flows from supply nodes to demand nodes at minimum cost, respecting the capacities of the arcs. Note that if the sum of supply attributes of all nodes is nonzero, the problem is infeasible.
MCF framework can be used to model a broad variety of network problems, including matching, shortest path, transportation, etc. For example, if we want to find the shortest paths from a source to all other nodes in a graph with n nodes, we can set the supply to n-1 for the source and to -1 for all other nodes, set capacity to n-1 and cost to the weight for each arc. The solution of the MCF problem with these particular settings will be minimum cost unit flow from the source to all other nodes passing by the shortest paths.
Problem data
The user of this class must store the problem data as attributes of the nodes
and the edges of the graph as described below. The names of these attributes
are specified in the constructor
NetworkSimplex(String, String, String). For efficiency reasons all
the data are supposed to be integer. If some of the attributes are real,
their fractional part is ignored. To avoid loss of precision, the user must
scale her data properly if they are real.
An attribute called supplyName is used to store the supply (or demand
if negative) of each node. If a node has not an attribute with this name or
if the value of this attribute is not numeric, the node supply is considered
as zero (transshipment node).
An attribute called capacityName is used to store the capacity of
each edge. If an edge has not an attribute with this name, or if the value of
this attribute is negative or not numeric, the edge capacity is considered as
infinite.
An attribute called costName is used to store the cost per unit flow
of each edge. If an edge has not an attribute with this name or if the value
of this attribute is not numeric, the cost per unit flow of the edge is
considered 1.
The flow on a directed edge is always from its source node to its target node. Each undirected edge is considered as a couple of directed edges with the same capacity and cost per unit flow. In other words, there are possibly two independent flows on each undirected edge.
Solutions
TODOVisualization
TODO- Author:
- Stefan Balev
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classNetworkSimplex.ArcStatusArc statusstatic classNetworkSimplex.PricingStrategyPricing strategy used at each iteration of the algorithm.static classNetworkSimplex.SolutionStatusThe status of the current solution. -
Field Summary
-
Constructor Summary
Constructors Constructor Description NetworkSimplex(String supplyName, String capaciyName, String costName)Creates a network simplex instance specifying attribute names to be used. -
Method Summary
Modifier and Type Method Description voidcompute()Run the algorithm.voidedgeAdded(String sourceId, long timeId, String edgeId, String fromNodeId, String toNodeId, boolean directed)voidedgeAttributeAdded(String sourceId, long timeId, String edgeId, String attribute, Object value)voidedgeAttributeChanged(String sourceId, long timeId, String edgeId, String attribute, Object oldValue, Object newValue)voidedgeAttributeRemoved(String sourceId, long timeId, String edgeId, String attribute)voidedgeRemoved(String sourceId, long timeId, String edgeId)StringgetCapacityName()Returns the name of the attribute used to store the capacity of each edge.StringgetCostName()Returns the name of the attribute used to store the cost per unit flow of each edge.org.graphstream.graph.EdgegetEdgeFromParent(org.graphstream.graph.Node node)Returns the edge to the parent of a node in the current BFS tree.intgetFlow(org.graphstream.graph.Edge edge)Returns the flow on an edge from its source node to its target node.intgetFlow(org.graphstream.graph.Edge edge, boolean sameDirection)Returns the flow on an edge.org.graphstream.graph.GraphgetGraph()Returns the graph on which the algorithm is applied.intgetInfeasibility(org.graphstream.graph.Node node)Returns the infeasibility of a node.intgetNetworkBalance()Returns the sum of the supplies of all the nodes in the network.org.graphstream.graph.NodegetParent(org.graphstream.graph.Node node)Returns the parent of a node in the current BFS tree.NetworkSimplex.PricingStrategygetPricingStrategy()Returns the currently used pricing strategy.longgetSolutionCost()Returns the total cost of the current network flowlonggetSolutionInfeasibility()Returns the infeasibility of the current solution.NetworkSimplex.SolutionStatusgetSolutionStatus()If the current solution is up to date, returns the status of the problem.NetworkSimplex.ArcStatusgetStatus(org.graphstream.graph.Edge edge)Returns the status of an edge in the current solution.NetworkSimplex.ArcStatusgetStatus(org.graphstream.graph.Edge edge, boolean sameDirection)Returns the status of an edge in the current solution.StringgetSupplyName()Returns the name of the attribute used to store the supply of each node.voidgraphCleared(String sourceId, long timeId)voidinit(org.graphstream.graph.Graph graph)Initialization of the algorithm.voidnodeAdded(String sourceId, long timeId, String nodeId)voidnodeAttributeAdded(String sourceId, long timeId, String nodeId, String attribute, Object value)voidnodeAttributeChanged(String sourceId, long timeId, String nodeId, String attribute, Object oldValue, Object newValue)voidnodeAttributeRemoved(String sourceId, long timeId, String nodeId, String attribute)voidnodeRemoved(String sourceId, long timeId, String nodeId)voidprintBFS(PrintStream ps)Prints a table containing informations about the current basic feasible solution.voidsetAnimationDelay(long millis)When the animation delay is positive, the algorithm continuously updates"ui.class"and"label"attributes of the edges and the nodes of the graph and sleeps at the beginning of each simplex pivot.voidsetLogFrequency(int pivots)Sets the log frequency.voidsetLogStream(PrintStream log)Sets the log stream.voidsetPricingStrategy(NetworkSimplex.PricingStrategy pricingStrategy)Sets the pricing strategyvoidsetUIClasses()This method can be used to visualize the current solution.voidterminate()Terminate the dynamic algorithm.
-
Field Details
-
PREFIX
The algorithm maintains some internal data whose names start with this prefix. The graph must not have any edges whose IDs start with this prefix.- See Also:
- Constant Field Values
-
-
Constructor Details
-
NetworkSimplex
Creates a network simplex instance specifying attribute names to be used. Useinit(Graph)to assign a graph to this instance.- Parameters:
supplyName- Name of the attribute used to store the supply of each node.capaciyName- Name of the attribute used to store the capacity of each edge.costName- Name of the attribute used to store the cost of each edge.
-
-
Method Details
-
getSupplyName
Returns the name of the attribute used to store the supply of each node. This name is given as constructor parameter and cannot be modified.- Returns:
- The name of the supply attribute.
-
getCapacityName
Returns the name of the attribute used to store the capacity of each edge. This name is given as constructor parameter and cannot be modified.- Returns:
- The name of the capacity attribute.
-
getCostName
Returns the name of the attribute used to store the cost per unit flow of each edge. This name is given as constructor parameter and cannot be modified.- Returns:
- The name of the cost attribute.
-
getPricingStrategy
Returns the currently used pricing strategy.- Returns:
- The pricing strategy
-
setPricingStrategy
Sets the pricing strategy- Parameters:
pricingStrategy- The new pricing strategy
-
setAnimationDelay
public void setAnimationDelay(long millis)When the animation delay is positive, the algorithm continuously updates"ui.class"and"label"attributes of the edges and the nodes of the graph and sleeps at the beginning of each simplex pivot. This feature can be useful for visualizing the algorithm execution. The user must provide a stylesheet defining the classes of the graph elements as described insetUIClasses(). This feature is disabled by default.- Parameters:
millis- The time in milliseconds to sleep between two simplex pivots.- See Also:
setUIClasses()
-
getGraph
public org.graphstream.graph.Graph getGraph()Returns the graph on which the algorithm is applied. This is the graph passed in parameter ininit(Graph).- Returns:
- The graph on which the algorithm is applied.
-
setLogFrequency
public void setLogFrequency(int pivots)Sets the log frequency. If the parameter is positive, outputs information about the algorithm execution to the log stream.- Parameters:
pivots- The log frequency in number of pivots- See Also:
setLogStream(PrintStream)
-
setLogStream
Sets the log stream. Note that the algorithm outputs information about its execution only if the log frequency is positive. By default the log stream isSystem.err.- Parameters:
log- The log stream- See Also:
setLogFrequency(int)
-
getNetworkBalance
public int getNetworkBalance()Returns the sum of the supplies of all the nodes in the network. The MCF problem has solution only if the problem is balanced, i.e. if the total supply is equal to the total demand. This method returns the missing supply (if negative) or demand (if positive) in order to make the problem balanced. If the returned value is zero, the problem is balanced.- Returns:
- The network balance
-
getSolutionStatus
If the current solution is up to date, returns the status of the problem. Otherwise returnsNetworkSimplex.SolutionStatus.UNDEFINED.- Returns:
- The status of the current solution.
- See Also:
NetworkSimplex.SolutionStatus
-
getSolutionCost
public long getSolutionCost()Returns the total cost of the current network flow- Returns:
- The cost of the flow defined by the current solution
-
getSolutionInfeasibility
public long getSolutionInfeasibility()Returns the infeasibility of the current solution. This is the sum of the absolute values of the infeasibilities of all the nodes. If the returned value is zero, the current solution is feasible, i.e. it satisfies the supply constraints of all the nodes.- Returns:
- The infeasibility of the current solution.
- See Also:
getInfeasibility(Node)
-
getInfeasibility
public int getInfeasibility(org.graphstream.graph.Node node)Returns the infeasibility of a node. Returns the amount of missing outflow (if positive) or inflow (if negative) of a given node. If the value is zero, the current solution satisfies the node demand / supply.- Parameters:
node- A node- Returns:
- The infeasibility of the node
-
getEdgeFromParent
public org.graphstream.graph.Edge getEdgeFromParent(org.graphstream.graph.Node node)Returns the edge to the parent of a node in the current BFS tree. If the parent of the node is the artificial root, this method returnsnull. When the returned edge is undirected, usegetStatus(Edge, boolean)to know which of the both arcs is basic.- Parameters:
node- A node- Returns:
- The edge to the parent of the node in the BFS tree
-
getParent
public org.graphstream.graph.Node getParent(org.graphstream.graph.Node node)Returns the parent of a node in the current BFS tree. If the parent of the node is the artificial root, returnsnull.- Parameters:
node- A node- Returns:
- The parent of a node in the BFS tree
-
getFlow
public int getFlow(org.graphstream.graph.Edge edge, boolean sameDirection)Returns the flow on an edge. IfsameDirectionis true, returns the flow from the source to the target of the edge, otherwise returns the flow from the target to the source of the edge. Note that for directed edges the flow can only pass from the source node to the target node. For undirected edges there may be independent flows in both directions.- Parameters:
edge- An edgesameDirection- If true, returns the flow from the source to the target.- Returns:
- The flow on the edge.
-
getFlow
public int getFlow(org.graphstream.graph.Edge edge)Returns the flow on an edge from its source node to its target node. The same asgetFlow(Edge, true).- Parameters:
edge- An edge- Returns:
- The flow on the edge
- See Also:
getFlow(Edge, boolean)
-
getStatus
Returns the status of an edge in the current solution. An edge can be basic, non-basic at zero or non-basic at upper bound. Note that undirected edges are interpreted as two directed arcs. IfsameDirectionis true, the method returns the status of the arc from the source to the target of the edge, otherwise it returns the status of the arc from the target to the source. If the edge is directed andsameDirectionis false, returnsnull.- Parameters:
edge- An edgesameDirection- If true, returns the status of the arc from the source to the target.- Returns:
- The status of the edge
-
getStatus
Returns the status of an edge in the current solution. The same asgetStatus(edge, true).- Parameters:
edge- An edge- Returns:
- The status of the edge
- See Also:
getStatus(Edge, boolean)
-
setUIClasses
public void setUIClasses()This method can be used to visualize the current solution.It sets the attributes
"label"and"ui.class"of the nodes and the edges of the graph depending on the current solution. The labels of the nodes are set to their balance (seegetInfeasibility(Node)). The labels of the edges are set to the flow passing through them. The"ui.class"attribute of the nodes is set to one of"supply_balanced","supply_unbalanced","demand_balanced","demand_unbalanced","trans_balanced"or"trans_unbalanced"depending on the node type and the node status. The"ui.class"attribute of the edges is set to one of"basic","nonbasic_lower"or"nonbasic_upper"according to their status (seegetStatus(Edge).The user must provide a stylesheet defining the visual appearance for each of these node and edge classes. Note that if the animation delay is positive (see
setAnimationDelay(long)), there is no need to call this method, because in this case the labels and the UI classes of the graph elements are set and updated during the algorithm execution.Note that in the case of undirected edges the label and the UI class are set according to the status of one of the corresponding arcs (not specified which one).
-
init
public void init(org.graphstream.graph.Graph graph)Description copied from interface:AlgorithmInitialization of the algorithm. This method has to be called before theAlgorithm.compute()method to initialize or reset the algorithm according to the new given graph. -
compute
public void compute()Description copied from interface:AlgorithmRun the algorithm. TheAlgorithm.init(Graph)method has to be called before computing.- Specified by:
computein interfaceAlgorithm- See Also:
Algorithm.init(Graph)
-
terminate
public void terminate()Description copied from interface:DynamicAlgorithmTerminate the dynamic algorithm.- Specified by:
terminatein interfaceDynamicAlgorithm- See Also:
Algorithm.init(org.graphstream.graph.Graph)
-
edgeAttributeAdded
public void edgeAttributeAdded(String sourceId, long timeId, String edgeId, String attribute, Object value)- Specified by:
edgeAttributeAddedin interfaceorg.graphstream.stream.AttributeSink- Overrides:
edgeAttributeAddedin classorg.graphstream.stream.SinkAdapter
-
edgeAttributeChanged
public void edgeAttributeChanged(String sourceId, long timeId, String edgeId, String attribute, Object oldValue, Object newValue)- Specified by:
edgeAttributeChangedin interfaceorg.graphstream.stream.AttributeSink- Overrides:
edgeAttributeChangedin classorg.graphstream.stream.SinkAdapter
-
edgeAttributeRemoved
- Specified by:
edgeAttributeRemovedin interfaceorg.graphstream.stream.AttributeSink- Overrides:
edgeAttributeRemovedin classorg.graphstream.stream.SinkAdapter
-
nodeAttributeAdded
public void nodeAttributeAdded(String sourceId, long timeId, String nodeId, String attribute, Object value)- Specified by:
nodeAttributeAddedin interfaceorg.graphstream.stream.AttributeSink- Overrides:
nodeAttributeAddedin classorg.graphstream.stream.SinkAdapter
-
nodeAttributeChanged
public void nodeAttributeChanged(String sourceId, long timeId, String nodeId, String attribute, Object oldValue, Object newValue)- Specified by:
nodeAttributeChangedin interfaceorg.graphstream.stream.AttributeSink- Overrides:
nodeAttributeChangedin classorg.graphstream.stream.SinkAdapter
-
nodeAttributeRemoved
- Specified by:
nodeAttributeRemovedin interfaceorg.graphstream.stream.AttributeSink- Overrides:
nodeAttributeRemovedin classorg.graphstream.stream.SinkAdapter
-
edgeAdded
public void edgeAdded(String sourceId, long timeId, String edgeId, String fromNodeId, String toNodeId, boolean directed)- Specified by:
edgeAddedin interfaceorg.graphstream.stream.ElementSink- Overrides:
edgeAddedin classorg.graphstream.stream.SinkAdapter
-
edgeRemoved
- Specified by:
edgeRemovedin interfaceorg.graphstream.stream.ElementSink- Overrides:
edgeRemovedin classorg.graphstream.stream.SinkAdapter
-
nodeAdded
- Specified by:
nodeAddedin interfaceorg.graphstream.stream.ElementSink- Overrides:
nodeAddedin classorg.graphstream.stream.SinkAdapter
-
nodeRemoved
- Specified by:
nodeRemovedin interfaceorg.graphstream.stream.ElementSink- Overrides:
nodeRemovedin classorg.graphstream.stream.SinkAdapter
-
graphCleared
- Specified by:
graphClearedin interfaceorg.graphstream.stream.ElementSink- Overrides:
graphClearedin classorg.graphstream.stream.SinkAdapter
-
printBFS
Prints a table containing informations about the current basic feasible solution. Useful for testing and debugging purposes.- Parameters:
ps- A stream where the output goes.
-