dust3d/thirdparty/QuadriFlow/3rd/lemon-1.3.1/lemon/min_cost_arborescence.h

809 lines
24 KiB
C++
Executable File

/* -*- mode: C++; indent-tabs-mode: nil; -*-
*
* This file is a part of LEMON, a generic C++ optimization library.
*
* Copyright (C) 2003-2013
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
* (Egervary Research Group on Combinatorial Optimization, EGRES).
*
* Permission to use, modify and distribute this software is granted
* provided that this copyright notice appears in all copies. For
* precise terms see the accompanying LICENSE file.
*
* This software is provided "AS IS" with no warranty of any kind,
* express or implied, and with no claim as to its suitability for any
* purpose.
*
*/
#ifndef LEMON_MIN_COST_ARBORESCENCE_H
#define LEMON_MIN_COST_ARBORESCENCE_H
///\ingroup spantree
///\file
///\brief Minimum Cost Arborescence algorithm.
#include <vector>
#include <lemon/list_graph.h>
#include <lemon/bin_heap.h>
#include <lemon/assert.h>
namespace lemon {
/// \brief Default traits class for MinCostArborescence class.
///
/// Default traits class for MinCostArborescence class.
/// \param GR Digraph type.
/// \param CM Type of the cost map.
template <class GR, class CM>
struct MinCostArborescenceDefaultTraits{
/// \brief The digraph type the algorithm runs on.
typedef GR Digraph;
/// \brief The type of the map that stores the arc costs.
///
/// The type of the map that stores the arc costs.
/// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
typedef CM CostMap;
/// \brief The value type of the costs.
///
/// The value type of the costs.
typedef typename CostMap::Value Value;
/// \brief The type of the map that stores which arcs are in the
/// arborescence.
///
/// The type of the map that stores which arcs are in the
/// arborescence. It must conform to the \ref concepts::WriteMap
/// "WriteMap" concept, and its value type must be \c bool
/// (or convertible). Initially it will be set to \c false on each
/// arc, then it will be set on each arborescence arc once.
typedef typename Digraph::template ArcMap<bool> ArborescenceMap;
/// \brief Instantiates a \c ArborescenceMap.
///
/// This function instantiates a \c ArborescenceMap.
/// \param digraph The digraph to which we would like to calculate
/// the \c ArborescenceMap.
static ArborescenceMap *createArborescenceMap(const Digraph &digraph){
return new ArborescenceMap(digraph);
}
/// \brief The type of the \c PredMap
///
/// The type of the \c PredMap. It must confrom to the
/// \ref concepts::WriteMap "WriteMap" concept, and its value type
/// must be the \c Arc type of the digraph.
typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
/// \brief Instantiates a \c PredMap.
///
/// This function instantiates a \c PredMap.
/// \param digraph The digraph to which we would like to define the
/// \c PredMap.
static PredMap *createPredMap(const Digraph &digraph){
return new PredMap(digraph);
}
};
/// \ingroup spantree
///
/// \brief Minimum Cost Arborescence algorithm class.
///
/// This class provides an efficient implementation of the
/// Minimum Cost Arborescence algorithm. The arborescence is a tree
/// which is directed from a given source node of the digraph. One or
/// more sources should be given to the algorithm and it will calculate
/// the minimum cost subgraph that is the union of arborescences with the
/// given sources and spans all the nodes which are reachable from the
/// sources. The time complexity of the algorithm is O(n<sup>2</sup>+m).
///
/// The algorithm also provides an optimal dual solution, therefore
/// the optimality of the solution can be checked.
///
/// \param GR The digraph type the algorithm runs on.
/// \param CM A read-only arc map storing the costs of the
/// arcs. It is read once for each arc, so the map may involve in
/// relatively time consuming process to compute the arc costs if
/// it is necessary. The default map type is \ref
/// concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
/// \tparam TR The traits class that defines various types used by the
/// algorithm. By default, it is \ref MinCostArborescenceDefaultTraits
/// "MinCostArborescenceDefaultTraits<GR, CM>".
/// In most cases, this parameter should not be set directly,
/// consider to use the named template parameters instead.
#ifndef DOXYGEN
template <typename GR,
typename CM = typename GR::template ArcMap<int>,
typename TR =
MinCostArborescenceDefaultTraits<GR, CM> >
#else
template <typename GR, typename CM, typename TR>
#endif
class MinCostArborescence {
public:
/// \brief The \ref lemon::MinCostArborescenceDefaultTraits "traits class"
/// of the algorithm.
typedef TR Traits;
/// The type of the underlying digraph.
typedef typename Traits::Digraph Digraph;
/// The type of the map that stores the arc costs.
typedef typename Traits::CostMap CostMap;
///The type of the costs of the arcs.
typedef typename Traits::Value Value;
///The type of the predecessor map.
typedef typename Traits::PredMap PredMap;
///The type of the map that stores which arcs are in the arborescence.
typedef typename Traits::ArborescenceMap ArborescenceMap;
typedef MinCostArborescence Create;
private:
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
struct CostArc {
Arc arc;
Value value;
CostArc() {}
CostArc(Arc _arc, Value _value) : arc(_arc), value(_value) {}
};
const Digraph *_digraph;
const CostMap *_cost;
PredMap *_pred;
bool local_pred;
ArborescenceMap *_arborescence;
bool local_arborescence;
typedef typename Digraph::template ArcMap<int> ArcOrder;
ArcOrder *_arc_order;
typedef typename Digraph::template NodeMap<int> NodeOrder;
NodeOrder *_node_order;
typedef typename Digraph::template NodeMap<CostArc> CostArcMap;
CostArcMap *_cost_arcs;
struct StackLevel {
std::vector<CostArc> arcs;
int node_level;
};
std::vector<StackLevel> level_stack;
std::vector<Node> queue;
typedef std::vector<typename Digraph::Node> DualNodeList;
DualNodeList _dual_node_list;
struct DualVariable {
int begin, end;
Value value;
DualVariable(int _begin, int _end, Value _value)
: begin(_begin), end(_end), value(_value) {}
};
typedef std::vector<DualVariable> DualVariables;
DualVariables _dual_variables;
typedef typename Digraph::template NodeMap<int> HeapCrossRef;
HeapCrossRef *_heap_cross_ref;
typedef BinHeap<int, HeapCrossRef> Heap;
Heap *_heap;
protected:
MinCostArborescence() {}
private:
void createStructures() {
if (!_pred) {
local_pred = true;
_pred = Traits::createPredMap(*_digraph);
}
if (!_arborescence) {
local_arborescence = true;
_arborescence = Traits::createArborescenceMap(*_digraph);
}
if (!_arc_order) {
_arc_order = new ArcOrder(*_digraph);
}
if (!_node_order) {
_node_order = new NodeOrder(*_digraph);
}
if (!_cost_arcs) {
_cost_arcs = new CostArcMap(*_digraph);
}
if (!_heap_cross_ref) {
_heap_cross_ref = new HeapCrossRef(*_digraph, -1);
}
if (!_heap) {
_heap = new Heap(*_heap_cross_ref);
}
}
void destroyStructures() {
if (local_arborescence) {
delete _arborescence;
}
if (local_pred) {
delete _pred;
}
if (_arc_order) {
delete _arc_order;
}
if (_node_order) {
delete _node_order;
}
if (_cost_arcs) {
delete _cost_arcs;
}
if (_heap) {
delete _heap;
}
if (_heap_cross_ref) {
delete _heap_cross_ref;
}
}
Arc prepare(Node node) {
std::vector<Node> nodes;
(*_node_order)[node] = _dual_node_list.size();
StackLevel level;
level.node_level = _dual_node_list.size();
_dual_node_list.push_back(node);
for (InArcIt it(*_digraph, node); it != INVALID; ++it) {
Arc arc = it;
Node source = _digraph->source(arc);
Value value = (*_cost)[it];
if (source == node || (*_node_order)[source] == -3) continue;
if ((*_cost_arcs)[source].arc == INVALID) {
(*_cost_arcs)[source].arc = arc;
(*_cost_arcs)[source].value = value;
nodes.push_back(source);
} else {
if ((*_cost_arcs)[source].value > value) {
(*_cost_arcs)[source].arc = arc;
(*_cost_arcs)[source].value = value;
}
}
}
CostArc minimum = (*_cost_arcs)[nodes[0]];
for (int i = 1; i < int(nodes.size()); ++i) {
if ((*_cost_arcs)[nodes[i]].value < minimum.value) {
minimum = (*_cost_arcs)[nodes[i]];
}
}
(*_arc_order)[minimum.arc] = _dual_variables.size();
DualVariable var(_dual_node_list.size() - 1,
_dual_node_list.size(), minimum.value);
_dual_variables.push_back(var);
for (int i = 0; i < int(nodes.size()); ++i) {
(*_cost_arcs)[nodes[i]].value -= minimum.value;
level.arcs.push_back((*_cost_arcs)[nodes[i]]);
(*_cost_arcs)[nodes[i]].arc = INVALID;
}
level_stack.push_back(level);
return minimum.arc;
}
Arc contract(Node node) {
int node_bottom = bottom(node);
std::vector<Node> nodes;
while (!level_stack.empty() &&
level_stack.back().node_level >= node_bottom) {
for (int i = 0; i < int(level_stack.back().arcs.size()); ++i) {
Arc arc = level_stack.back().arcs[i].arc;
Node source = _digraph->source(arc);
Value value = level_stack.back().arcs[i].value;
if ((*_node_order)[source] >= node_bottom) continue;
if ((*_cost_arcs)[source].arc == INVALID) {
(*_cost_arcs)[source].arc = arc;
(*_cost_arcs)[source].value = value;
nodes.push_back(source);
} else {
if ((*_cost_arcs)[source].value > value) {
(*_cost_arcs)[source].arc = arc;
(*_cost_arcs)[source].value = value;
}
}
}
level_stack.pop_back();
}
CostArc minimum = (*_cost_arcs)[nodes[0]];
for (int i = 1; i < int(nodes.size()); ++i) {
if ((*_cost_arcs)[nodes[i]].value < minimum.value) {
minimum = (*_cost_arcs)[nodes[i]];
}
}
(*_arc_order)[minimum.arc] = _dual_variables.size();
DualVariable var(node_bottom, _dual_node_list.size(), minimum.value);
_dual_variables.push_back(var);
StackLevel level;
level.node_level = node_bottom;
for (int i = 0; i < int(nodes.size()); ++i) {
(*_cost_arcs)[nodes[i]].value -= minimum.value;
level.arcs.push_back((*_cost_arcs)[nodes[i]]);
(*_cost_arcs)[nodes[i]].arc = INVALID;
}
level_stack.push_back(level);
return minimum.arc;
}
int bottom(Node node) {
int k = level_stack.size() - 1;
while (level_stack[k].node_level > (*_node_order)[node]) {
--k;
}
return level_stack[k].node_level;
}
void finalize(Arc arc) {
Node node = _digraph->target(arc);
_heap->push(node, (*_arc_order)[arc]);
_pred->set(node, arc);
while (!_heap->empty()) {
Node source = _heap->top();
_heap->pop();
(*_node_order)[source] = -1;
for (OutArcIt it(*_digraph, source); it != INVALID; ++it) {
if ((*_arc_order)[it] < 0) continue;
Node target = _digraph->target(it);
switch(_heap->state(target)) {
case Heap::PRE_HEAP:
_heap->push(target, (*_arc_order)[it]);
_pred->set(target, it);
break;
case Heap::IN_HEAP:
if ((*_arc_order)[it] < (*_heap)[target]) {
_heap->decrease(target, (*_arc_order)[it]);
_pred->set(target, it);
}
break;
case Heap::POST_HEAP:
break;
}
}
_arborescence->set((*_pred)[source], true);
}
}
public:
/// \name Named Template Parameters
/// @{
template <class T>
struct SetArborescenceMapTraits : public Traits {
typedef T ArborescenceMap;
static ArborescenceMap *createArborescenceMap(const Digraph &)
{
LEMON_ASSERT(false, "ArborescenceMap is not initialized");
return 0; // ignore warnings
}
};
/// \brief \ref named-templ-param "Named parameter" for
/// setting \c ArborescenceMap type
///
/// \ref named-templ-param "Named parameter" for setting
/// \c ArborescenceMap type.
/// It must conform to the \ref concepts::WriteMap "WriteMap" concept,
/// and its value type must be \c bool (or convertible).
/// Initially it will be set to \c false on each arc,
/// then it will be set on each arborescence arc once.
template <class T>
struct SetArborescenceMap
: public MinCostArborescence<Digraph, CostMap,
SetArborescenceMapTraits<T> > {
};
template <class T>
struct SetPredMapTraits : public Traits {
typedef T PredMap;
static PredMap *createPredMap(const Digraph &)
{
LEMON_ASSERT(false, "PredMap is not initialized");
return 0; // ignore warnings
}
};
/// \brief \ref named-templ-param "Named parameter" for
/// setting \c PredMap type
///
/// \ref named-templ-param "Named parameter" for setting
/// \c PredMap type.
/// It must meet the \ref concepts::WriteMap "WriteMap" concept,
/// and its value type must be the \c Arc type of the digraph.
template <class T>
struct SetPredMap
: public MinCostArborescence<Digraph, CostMap, SetPredMapTraits<T> > {
};
/// @}
/// \brief Constructor.
///
/// \param digraph The digraph the algorithm will run on.
/// \param cost The cost map used by the algorithm.
MinCostArborescence(const Digraph& digraph, const CostMap& cost)
: _digraph(&digraph), _cost(&cost), _pred(0), local_pred(false),
_arborescence(0), local_arborescence(false),
_arc_order(0), _node_order(0), _cost_arcs(0),
_heap_cross_ref(0), _heap(0) {}
/// \brief Destructor.
~MinCostArborescence() {
destroyStructures();
}
/// \brief Sets the arborescence map.
///
/// Sets the arborescence map.
/// \return <tt>(*this)</tt>
MinCostArborescence& arborescenceMap(ArborescenceMap& m) {
if (local_arborescence) {
delete _arborescence;
}
local_arborescence = false;
_arborescence = &m;
return *this;
}
/// \brief Sets the predecessor map.
///
/// Sets the predecessor map.
/// \return <tt>(*this)</tt>
MinCostArborescence& predMap(PredMap& m) {
if (local_pred) {
delete _pred;
}
local_pred = false;
_pred = &m;
return *this;
}
/// \name Execution Control
/// The simplest way to execute the algorithm is to use
/// one of the member functions called \c run(...). \n
/// If you need better control on the execution,
/// you have to call \ref init() first, then you can add several
/// source nodes with \ref addSource().
/// Finally \ref start() will perform the arborescence
/// computation.
///@{
/// \brief Initializes the internal data structures.
///
/// Initializes the internal data structures.
///
void init() {
createStructures();
_heap->clear();
for (NodeIt it(*_digraph); it != INVALID; ++it) {
(*_cost_arcs)[it].arc = INVALID;
(*_node_order)[it] = -3;
(*_heap_cross_ref)[it] = Heap::PRE_HEAP;
_pred->set(it, INVALID);
}
for (ArcIt it(*_digraph); it != INVALID; ++it) {
_arborescence->set(it, false);
(*_arc_order)[it] = -1;
}
_dual_node_list.clear();
_dual_variables.clear();
}
/// \brief Adds a new source node.
///
/// Adds a new source node to the algorithm.
void addSource(Node source) {
std::vector<Node> nodes;
nodes.push_back(source);
while (!nodes.empty()) {
Node node = nodes.back();
nodes.pop_back();
for (OutArcIt it(*_digraph, node); it != INVALID; ++it) {
Node target = _digraph->target(it);
if ((*_node_order)[target] == -3) {
(*_node_order)[target] = -2;
nodes.push_back(target);
queue.push_back(target);
}
}
}
(*_node_order)[source] = -1;
}
/// \brief Processes the next node in the priority queue.
///
/// Processes the next node in the priority queue.
///
/// \return The processed node.
///
/// \warning The queue must not be empty.
Node processNextNode() {
Node node = queue.back();
queue.pop_back();
if ((*_node_order)[node] == -2) {
Arc arc = prepare(node);
Node source = _digraph->source(arc);
while ((*_node_order)[source] != -1) {
if ((*_node_order)[source] >= 0) {
arc = contract(source);
} else {
arc = prepare(source);
}
source = _digraph->source(arc);
}
finalize(arc);
level_stack.clear();
}
return node;
}
/// \brief Returns the number of the nodes to be processed.
///
/// Returns the number of the nodes to be processed in the priority
/// queue.
int queueSize() const {
return queue.size();
}
/// \brief Returns \c false if there are nodes to be processed.
///
/// Returns \c false if there are nodes to be processed.
bool emptyQueue() const {
return queue.empty();
}
/// \brief Executes the algorithm.
///
/// Executes the algorithm.
///
/// \pre init() must be called and at least one node should be added
/// with addSource() before using this function.
///
///\note mca.start() is just a shortcut of the following code.
///\code
///while (!mca.emptyQueue()) {
/// mca.processNextNode();
///}
///\endcode
void start() {
while (!emptyQueue()) {
processNextNode();
}
}
/// \brief Runs %MinCostArborescence algorithm from node \c s.
///
/// This method runs the %MinCostArborescence algorithm from
/// a root node \c s.
///
/// \note mca.run(s) is just a shortcut of the following code.
/// \code
/// mca.init();
/// mca.addSource(s);
/// mca.start();
/// \endcode
void run(Node s) {
init();
addSource(s);
start();
}
///@}
/// \name Query Functions
/// The result of the %MinCostArborescence algorithm can be obtained
/// using these functions.\n
/// Either run() or start() must be called before using them.
/// @{
/// \brief Returns the cost of the arborescence.
///
/// Returns the cost of the arborescence.
Value arborescenceCost() const {
Value sum = 0;
for (ArcIt it(*_digraph); it != INVALID; ++it) {
if (arborescence(it)) {
sum += (*_cost)[it];
}
}
return sum;
}
/// \brief Returns \c true if the arc is in the arborescence.
///
/// Returns \c true if the given arc is in the arborescence.
/// \param arc An arc of the digraph.
/// \pre \ref run() must be called before using this function.
bool arborescence(Arc arc) const {
return (*_pred)[_digraph->target(arc)] == arc;
}
/// \brief Returns a const reference to the arborescence map.
///
/// Returns a const reference to the arborescence map.
/// \pre \ref run() must be called before using this function.
const ArborescenceMap& arborescenceMap() const {
return *_arborescence;
}
/// \brief Returns the predecessor arc of the given node.
///
/// Returns the predecessor arc of the given node.
/// \pre \ref run() must be called before using this function.
Arc pred(Node node) const {
return (*_pred)[node];
}
/// \brief Returns a const reference to the pred map.
///
/// Returns a const reference to the pred map.
/// \pre \ref run() must be called before using this function.
const PredMap& predMap() const {
return *_pred;
}
/// \brief Indicates that a node is reachable from the sources.
///
/// Indicates that a node is reachable from the sources.
bool reached(Node node) const {
return (*_node_order)[node] != -3;
}
/// \brief Indicates that a node is processed.
///
/// Indicates that a node is processed. The arborescence path exists
/// from the source to the given node.
bool processed(Node node) const {
return (*_node_order)[node] == -1;
}
/// \brief Returns the number of the dual variables in basis.
///
/// Returns the number of the dual variables in basis.
int dualNum() const {
return _dual_variables.size();
}
/// \brief Returns the value of the dual solution.
///
/// Returns the value of the dual solution. It should be
/// equal to the arborescence value.
Value dualValue() const {
Value sum = 0;
for (int i = 0; i < int(_dual_variables.size()); ++i) {
sum += _dual_variables[i].value;
}
return sum;
}
/// \brief Returns the number of the nodes in the dual variable.
///
/// Returns the number of the nodes in the dual variable.
int dualSize(int k) const {
return _dual_variables[k].end - _dual_variables[k].begin;
}
/// \brief Returns the value of the dual variable.
///
/// Returns the the value of the dual variable.
Value dualValue(int k) const {
return _dual_variables[k].value;
}
/// \brief LEMON iterator for getting a dual variable.
///
/// This class provides a common style LEMON iterator for getting a
/// dual variable of \ref MinCostArborescence algorithm.
/// It iterates over a subset of the nodes.
class DualIt {
public:
/// \brief Constructor.
///
/// Constructor for getting the nodeset of the dual variable
/// of \ref MinCostArborescence algorithm.
DualIt(const MinCostArborescence& algorithm, int variable)
: _algorithm(&algorithm)
{
_index = _algorithm->_dual_variables[variable].begin;
_last = _algorithm->_dual_variables[variable].end;
}
/// \brief Conversion to \c Node.
///
/// Conversion to \c Node.
operator Node() const {
return _algorithm->_dual_node_list[_index];
}
/// \brief Increment operator.
///
/// Increment operator.
DualIt& operator++() {
++_index;
return *this;
}
/// \brief Validity checking
///
/// Checks whether the iterator is invalid.
bool operator==(Invalid) const {
return _index == _last;
}
/// \brief Validity checking
///
/// Checks whether the iterator is valid.
bool operator!=(Invalid) const {
return _index != _last;
}
private:
const MinCostArborescence* _algorithm;
int _index, _last;
};
/// @}
};
/// \ingroup spantree
///
/// \brief Function type interface for MinCostArborescence algorithm.
///
/// Function type interface for MinCostArborescence algorithm.
/// \param digraph The digraph the algorithm runs on.
/// \param cost An arc map storing the costs.
/// \param source The source node of the arborescence.
/// \retval arborescence An arc map with \c bool (or convertible) value
/// type that stores the arborescence.
/// \return The total cost of the arborescence.
///
/// \sa MinCostArborescence
template <typename Digraph, typename CostMap, typename ArborescenceMap>
typename CostMap::Value minCostArborescence(const Digraph& digraph,
const CostMap& cost,
typename Digraph::Node source,
ArborescenceMap& arborescence) {
typename MinCostArborescence<Digraph, CostMap>
::template SetArborescenceMap<ArborescenceMap>
::Create mca(digraph, cost);
mca.arborescenceMap(arborescence);
mca.run(source);
return mca.arborescenceCost();
}
}
#endif