123 #ifndef OR_TOOLS_GRAPH_MAX_FLOW_H_ 124 #define OR_TOOLS_GRAPH_MAX_FLOW_H_ 131 #include "ortools/base/integral_types.h" 132 #include "ortools/base/logging.h" 133 #include "ortools/base/macros.h" 135 #include "ortools/graph/flow_problem.pb.h" 137 #include "ortools/util/stats.h" 138 #include "ortools/util/zvector.h" 143 template <
typename Graph>
233 std::vector<NodeIndex> arc_tail_;
234 std::vector<NodeIndex> arc_head_;
235 std::vector<FlowQuantity> arc_capacity_;
236 std::vector<ArcIndex> arc_permutation_;
237 std::vector<FlowQuantity> arc_flow_;
242 typedef ::util::ReverseArcStaticGraph<NodeIndex, ArcIndex> Graph;
243 std::unique_ptr<Graph> underlying_graph_;
244 std::unique_ptr<GenericMaxFlow<Graph> > underlying_max_flow_;
263 template <
typename Element,
typename IntegerPriority>
277 void Push(Element element, IntegerPriority priority);
285 Element PopBack(std::vector<std::pair<Element, IntegerPriority> >* queue);
290 std::vector<std::pair<Element, IntegerPriority> > even_queue_;
291 std::vector<std::pair<Element, IntegerPriority> > odd_queue_;
314 template <
typename Graph>
315 class GenericMaxFlow :
public MaxFlowStatusClass {
320 typedef typename Graph::OutgoingOrOppositeIncomingArcIterator
540 template <
bool reverse>
660 template <
typename Element,
typename IntegerPriority>
663 return even_queue_.empty() && odd_queue_.empty();
666 template <
typename Element,
typename IntegerPriority>
672 template <
typename Element,
typename IntegerPriority>
674 Element element, IntegerPriority priority) {
676 DCHECK(even_queue_.empty() || priority >= even_queue_.back().second - 1);
677 DCHECK(odd_queue_.empty() || priority >= odd_queue_.back().second - 1);
683 DCHECK(odd_queue_.empty() || priority >= odd_queue_.back().second);
684 odd_queue_.push_back(std::make_pair(element, priority));
686 DCHECK(even_queue_.empty() || priority >= even_queue_.back().second);
687 even_queue_.push_back(std::make_pair(element, priority));
691 template <
typename Element,
typename IntegerPriority>
694 if (even_queue_.empty())
return PopBack(&odd_queue_);
695 if (odd_queue_.empty())
return PopBack(&even_queue_);
696 if (odd_queue_.back().second > even_queue_.back().second) {
697 return PopBack(&odd_queue_);
699 return PopBack(&even_queue_);
703 template <
typename Element,
typename IntegerPriority>
705 std::vector<std::pair<Element, IntegerPriority> >* queue) {
706 DCHECK(!queue->empty());
707 Element element = queue->back().first;
713 #endif // OR_TOOLS_GRAPH_MAX_FLOW_H_ NodeIndex sink_
The index of the sink node in graph_.
bool check_result_
Whether or not we check the result.
Specific but efficient priority queue implementation.
A simple and efficient max-cost flow interface.
Graph::IncomingArcIterator IncomingArcIterator
FlowQuantity OptimalFlow() const
Returns the maximum flow we can send from the source to the sink in the last OPTIMAL Solve() context.
const Graph * graph() const
Returns the graph associated to the current object.
NodeIndex GetSourceNodeIndex() const
Returns the index of the node corresponding to the source of the network.
std::vector< NodeIndex > bfs_queue_
bool check_input_
Whether or not we check the input, this is a small price to pay for robustness.
void SetUseTwoPhaseAlgorithm(bool value)
void SetArcFlow(ArcIndex arc, FlowQuantity new_flow)
Sets the flow for arc.
void SetCheckResult(bool value)
void GetSinkSideMinCut(std::vector< NodeIndex > *result)
Returns the nodes that can reach the sink by non-saturated arcs, the outgoing arcs of this set form a...
QuantityArray node_excess_
An array representing the excess for each node in graph_.
PriorityQueueWithRestrictedPush< NodeIndex, NodeHeight > active_node_by_height_
A priority queue used for managing active nodes in the algorithm.
ListGraph Graph
Defining the simplest Graph interface as Graph for convenience.
FlowModel CreateFlowModelOfLastSolve()
Creates the protocol buffer representation of the problem used by the last Solve() call.
Status status() const
Returns the status of last call to Solve().
The input is inconsistent (bad tail/head/capacity values).
bool CheckInputConsistency() const
Checks the consistency of the input, i.e.
ArcIndex Opposite(ArcIndex arc) const
bool SaturateOutgoingArcsFromSource()
Tries to saturate all the outgoing arcs from the source that can reach the sink.
std::vector< bool > node_in_bfs_queue_
BFS queue used by the GlobalUpdate() function.
We want an enum for the Status of a max flow run, and we want this enum to be scoped under GenericMax...
bool CheckRelabelPrecondition(NodeIndex node) const
Returns true if a precondition for Relabel is met, i.e.
Status
Solves the problem (finds the maximum flow from the given source to the given sink),...
MaxFlow(const StarGraph *graph, NodeIndex source, NodeIndex target)
Status status_
The status of the problem.
void Discharge(NodeIndex node)
Discharges an active node node by saturating its admissible adjacent arcs, if any,...
void Relabel(NodeIndex node)
Relabels a node, i.e.
void InitializeActiveNodeContainer()
Initializes the container active_nodes_.
NodeIndex GetSinkNodeIndex() const
Returns the index of the node corresponding to the sink of the network.
FlowModel CreateFlowModel()
Returns the protocol buffer representation of the current problem.
void InitializePreflow()
Initializes the preflow to a state that enables to run Refine.
void PushFlowExcessBackToSource()
Clears the flow excess at each node by pushing the flow back to the source:
FlowQuantity Flow(ArcIndex arc) const
Returns the flow on arc using the equations given in the comment on residual_arc_capacity_.
There is a flow > std::numeric_limits<FlowQuantity>::max().
bool IsEmpty() const
Is the queue empty?
ArcIndex AddArcWithCapacity(NodeIndex tail, NodeIndex head, FlowQuantity capacity)
Adds a directed arc with the given capacity from tail to head.
void ProcessNodeByHeight(bool value)
void GetSourceSideMinCut(std::vector< NodeIndex > *result)
Returns the nodes reachable from the source by non-saturated arcs (.i.e.
bool AugmentingPathExists() const
Returns true if there exists a path from the source to the sink with remaining capacity.
PriorityQueueWithRestrictedPush()
void GetSourceSideMinCut(std::vector< NodeIndex > *result)
Returns the nodes reachable from the source in the residual graph, the outgoing arcs of this set form...
ZVector< NodeHeight > NodeHeightArray
void Push(Element element, IntegerPriority priority)
Push a new element in the queue.
ZVector< FlowQuantity > QuantityArray
FlowQuantity GetOptimalFlow() const
Returns the total flow found by the algorithm.
NodeHeightArray node_potential_
An array representing the height function for each node in graph_.
void RefineWithGlobalUpdate()
ArcIndex NumArcs() const
Returns the current number of arcs in the graph.
ZVector< ArcIndex > ArcIndexArray
NodeIndex Head(ArcIndex arc) const
Graph::OutgoingArcIterator OutgoingArcIterator
FlowQuantity Capacity(ArcIndex arc) const
Returns the capacity of arc using the equations given in the comment on residual_arc_capacity_.
bool IsActive(NodeIndex node) const
Returns true if node is active, i.e.
NodeIndex Tail(ArcIndex arc) const
QuantityArray residual_arc_capacity_
An array representing the residual_capacity for each arc in graph_.
NodeIndex NodeHeight
The height of a node never excess 2 times the number of node, so we use the same type as a Node index...
void SetCheckInput(bool value)
Status Solve(NodeIndex source, NodeIndex sink)
FlowQuantity Flow(ArcIndex arc) const
Returns the flow on the given arc in the last OPTIMAL Solve() context.
void PushActiveNode(const NodeIndex &node)
Push element to the active node container.
std::vector< NodeIndex > active_nodes_
A stack used for managing active nodes in the algorithm.
void Clear()
Clears the queue.
const Graph * graph_
A pointer to the graph passed as argument.
Graph::NodeIndex NodeIndex
std::string DebugString(const std::string &context, ArcIndex arc) const
Returns context concatenated with information about arc in a human-friendly way.
FlowQuantity Capacity(ArcIndex arc) const
bool IsAdmissible(ArcIndex arc) const
Returns true if arc is admissible.
void ComputeReachableNodes(NodeIndex start, std::vector< NodeIndex > *result)
Returns the set of nodes reachable from start in the residual graph or in the reverse residual graph ...
void PushFlow(FlowQuantity flow, ArcIndex arc)
Pushes flow on arc, i.e.
virtual ~GenericMaxFlow()
void GetSinkSideMinCut(std::vector< NodeIndex > *result)
Returns the nodes that can reach the sink in the residual graph, the outgoing arcs of this set form a...
Element Pop()
Returns the element with highest priority and remove it from the queue.
bool IsArcDirect(ArcIndex arc) const
bool Solve()
Returns true if a maximum flow was solved.
Default instance MaxFlow that uses StarGraph.
bool use_two_phase_algorithm_
Whether or not we use a two-phase algorithm: 1/ Only deal with nodes that can reach the sink.
StatsGroup stats_
Statistics about this class.
GenericMaxFlow(const Graph *graph, NodeIndex source, NodeIndex sink)
Initialize a MaxFlow instance on the given graph.
void Refine()
Performs optimization step.
void SetArcCapacity(ArcIndex arc, FlowQuantity capacity)
Change the capacity of an arc.
void SetCapacityAndClearFlow(ArcIndex arc, FlowQuantity capacity)
Sets the capacity of arc to 'capacity' and clears the flow on arc.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in c...
bool use_global_update_
Whether or not to use GlobalUpdate().
NodeIndex NumNodes() const
Returns the current number of nodes.
NodeIndex Head(ArcIndex arc) const
Handy member functions to make the code more compact.
void SetUseGlobalUpdate(bool value)
Sets the different algorithm options.
bool IsEmptyActiveNodeContainer()
Check the emptiness of the container.
void SetArcCapacity(ArcIndex arc, FlowQuantity new_capacity)
Sets the capacity for arc to new_capacity.
NodeIndex source_
The index of the source node in graph_.
SimpleMaxFlow()
The constructor takes no size.
bool process_node_by_height_
Whether or not we use the PriorityQueueWithRestrictedPush to process the active nodes rather than a s...
static const FlowQuantity kMaxFlowQuantity
Maximum manageable flow.
Graph::OutgoingOrOppositeIncomingArcIterator OutgoingOrOppositeIncomingArcIterator
bool IsArcValid(ArcIndex arc) const
int32 NodeIndex
Standard instantiation of ForwardEbertGraph (named 'ForwardStarGraph') of EbertGraph (named 'StarGrap...
This should not happen. There was an error in our code (i.e. file a bug).
NodeIndex Tail(ArcIndex arc) const
Returns user-provided data.
bool CheckResult() const
Checks whether the result is valid, i.e.
ArcIndexArray first_admissible_arc_
An array representing the first admissible arc for each node in graph_.
NodeIndex GetAndRemoveFirstActiveNode()
Get the first element from the active node container.
Solve() was called and found an optimal solution.
void GlobalUpdate()
Computes the best possible node potential given the current flow using a reverse breadth-first search...