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 class
NetworkSimplex.ArcStatus
Arc statusstatic class
NetworkSimplex.PricingStrategy
Pricing strategy used at each iteration of the algorithm.static class
NetworkSimplex.SolutionStatus
The 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 void
compute()
Run the algorithm.void
edgeAdded(String sourceId, long timeId, String edgeId, String fromNodeId, String toNodeId, boolean directed)
void
edgeAttributeAdded(String sourceId, long timeId, String edgeId, String attribute, Object value)
void
edgeAttributeChanged(String sourceId, long timeId, String edgeId, String attribute, Object oldValue, Object newValue)
void
edgeAttributeRemoved(String sourceId, long timeId, String edgeId, String attribute)
void
edgeRemoved(String sourceId, long timeId, String edgeId)
String
getCapacityName()
Returns the name of the attribute used to store the capacity of each edge.String
getCostName()
Returns the name of the attribute used to store the cost per unit flow of each edge.org.graphstream.graph.Edge
getEdgeFromParent(org.graphstream.graph.Node node)
Returns the edge to the parent of a node in the current BFS tree.int
getFlow(org.graphstream.graph.Edge edge)
Returns the flow on an edge from its source node to its target node.int
getFlow(org.graphstream.graph.Edge edge, boolean sameDirection)
Returns the flow on an edge.org.graphstream.graph.Graph
getGraph()
Returns the graph on which the algorithm is applied.int
getInfeasibility(org.graphstream.graph.Node node)
Returns the infeasibility of a node.int
getNetworkBalance()
Returns the sum of the supplies of all the nodes in the network.org.graphstream.graph.Node
getParent(org.graphstream.graph.Node node)
Returns the parent of a node in the current BFS tree.NetworkSimplex.PricingStrategy
getPricingStrategy()
Returns the currently used pricing strategy.long
getSolutionCost()
Returns the total cost of the current network flowlong
getSolutionInfeasibility()
Returns the infeasibility of the current solution.NetworkSimplex.SolutionStatus
getSolutionStatus()
If the current solution is up to date, returns the status of the problem.NetworkSimplex.ArcStatus
getStatus(org.graphstream.graph.Edge edge)
Returns the status of an edge in the current solution.NetworkSimplex.ArcStatus
getStatus(org.graphstream.graph.Edge edge, boolean sameDirection)
Returns the status of an edge in the current solution.String
getSupplyName()
Returns the name of the attribute used to store the supply of each node.void
graphCleared(String sourceId, long timeId)
void
init(org.graphstream.graph.Graph graph)
Initialization of the algorithm.void
nodeAdded(String sourceId, long timeId, String nodeId)
void
nodeAttributeAdded(String sourceId, long timeId, String nodeId, String attribute, Object value)
void
nodeAttributeChanged(String sourceId, long timeId, String nodeId, String attribute, Object oldValue, Object newValue)
void
nodeAttributeRemoved(String sourceId, long timeId, String nodeId, String attribute)
void
nodeRemoved(String sourceId, long timeId, String nodeId)
void
printBFS(PrintStream ps)
Prints a table containing informations about the current basic feasible solution.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.void
setLogFrequency(int pivots)
Sets the log frequency.void
setLogStream(PrintStream log)
Sets the log stream.void
setPricingStrategy(NetworkSimplex.PricingStrategy pricingStrategy)
Sets the pricing strategyvoid
setUIClasses()
This method can be used to visualize the current solution.void
terminate()
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. IfsameDirection
is 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. IfsameDirection
is 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 andsameDirection
is 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:Algorithm
Initialization 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:Algorithm
Run the algorithm. TheAlgorithm.init(Graph)
method has to be called before computing.- Specified by:
compute
in interfaceAlgorithm
- See Also:
Algorithm.init(Graph)
-
terminate
public void terminate()Description copied from interface:DynamicAlgorithm
Terminate the dynamic algorithm.- Specified by:
terminate
in 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:
edgeAttributeAdded
in interfaceorg.graphstream.stream.AttributeSink
- Overrides:
edgeAttributeAdded
in classorg.graphstream.stream.SinkAdapter
-
edgeAttributeChanged
public void edgeAttributeChanged(String sourceId, long timeId, String edgeId, String attribute, Object oldValue, Object newValue)- Specified by:
edgeAttributeChanged
in interfaceorg.graphstream.stream.AttributeSink
- Overrides:
edgeAttributeChanged
in classorg.graphstream.stream.SinkAdapter
-
edgeAttributeRemoved
- Specified by:
edgeAttributeRemoved
in interfaceorg.graphstream.stream.AttributeSink
- Overrides:
edgeAttributeRemoved
in classorg.graphstream.stream.SinkAdapter
-
nodeAttributeAdded
public void nodeAttributeAdded(String sourceId, long timeId, String nodeId, String attribute, Object value)- Specified by:
nodeAttributeAdded
in interfaceorg.graphstream.stream.AttributeSink
- Overrides:
nodeAttributeAdded
in classorg.graphstream.stream.SinkAdapter
-
nodeAttributeChanged
public void nodeAttributeChanged(String sourceId, long timeId, String nodeId, String attribute, Object oldValue, Object newValue)- Specified by:
nodeAttributeChanged
in interfaceorg.graphstream.stream.AttributeSink
- Overrides:
nodeAttributeChanged
in classorg.graphstream.stream.SinkAdapter
-
nodeAttributeRemoved
- Specified by:
nodeAttributeRemoved
in interfaceorg.graphstream.stream.AttributeSink
- Overrides:
nodeAttributeRemoved
in classorg.graphstream.stream.SinkAdapter
-
edgeAdded
public void edgeAdded(String sourceId, long timeId, String edgeId, String fromNodeId, String toNodeId, boolean directed)- Specified by:
edgeAdded
in interfaceorg.graphstream.stream.ElementSink
- Overrides:
edgeAdded
in classorg.graphstream.stream.SinkAdapter
-
edgeRemoved
- Specified by:
edgeRemoved
in interfaceorg.graphstream.stream.ElementSink
- Overrides:
edgeRemoved
in classorg.graphstream.stream.SinkAdapter
-
nodeAdded
- Specified by:
nodeAdded
in interfaceorg.graphstream.stream.ElementSink
- Overrides:
nodeAdded
in classorg.graphstream.stream.SinkAdapter
-
nodeRemoved
- Specified by:
nodeRemoved
in interfaceorg.graphstream.stream.ElementSink
- Overrides:
nodeRemoved
in classorg.graphstream.stream.SinkAdapter
-
graphCleared
- Specified by:
graphCleared
in interfaceorg.graphstream.stream.ElementSink
- Overrides:
graphCleared
in 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.
-