8#ifndef LIMBO_SOLVERS_DUALMINCOSTFLOW_H
9#define LIMBO_SOLVERS_DUALMINCOSTFLOW_H
11#include <lemon/smart_graph.h>
12#include <lemon/network_simplex.h>
13#include <lemon/cost_scaling.h>
14#include <lemon/capacity_scaling.h>
15#include <lemon/cycle_canceling.h>
16#include <lemon/lgf_writer.h>
28template <
typename T,
typename V>
30template <
typename T,
typename V>
32template <
typename T,
typename V>
34template <
typename T,
typename V>
36template <
typename T,
typename V>
101template <
typename T,
typename V>
110 typedef variable_value_type value_type;
117 typedef lemon::SmartDigraph graph_type;
118 typedef graph_type::Node node_type;
119 typedef graph_type::Arc arc_type;
120 typedef graph_type::NodeMap<value_type> node_value_map_type;
121 typedef graph_type::NodeMap<std::string> node_name_map_type;
122 typedef graph_type::ArcMap<value_type> arc_value_map_type;
123 typedef graph_type::ArcMap<value_type> arc_cost_map_type;
124 typedef graph_type::ArcMap<value_type> arc_flow_map_type;
125 typedef graph_type::NodeMap<value_type> node_pot_map_type;
155 return solve(solver);
170 graph_type
const&
graph()
const;
174 arc_value_map_type
const&
upperMap()
const;
176 arc_cost_map_type
const&
costMap()
const;
178 node_value_map_type
const&
supplyMap()
const;
246template <
typename T,
typename V>
251template <
typename T,
typename V>
256template <
typename T,
typename V>
261template <
typename T,
typename V>
266template <
typename T,
typename V>
276template <
typename T,
typename V>
281template <
typename T,
typename V>
286template <
typename T,
typename V>
291template <
typename T,
typename V>
296template <
typename T,
typename V>
301template <
typename T,
typename V>
306template <
typename T,
typename V>
311template <
typename T,
typename V>
318template <
typename T,
typename V>
325 node_name_map_type nameMap (
m_graph);
326 for (
unsigned int i = 0, ie =
m_model->numVariables(); i < ie; ++i)
327 nameMap[
m_graph.nodeFromId(i)] =
m_model->variableName(variable_type(i));
331 lemon::DigraphWriter<graph_type> writer(
m_graph,
"debug.lgf");
333 .nodeMap(
"name", nameMap)
341template <
typename T,
typename V>
344 bool defaultSolver =
false;
349 defaultSolver =
true;
353 if (
m_model->numVariables() == 0)
360#ifdef DEBUG_DUALMINCOSTFLOW
363 coefficient_value_type totalSupply = 0;
364 for (graph_type::NodeIt it (
m_graph); it != lemon::INVALID; ++it)
373#ifdef DEBUG_DUALMINCOSTFLOW
382template <
typename T,
typename V>
388 if (
m_diffBigM == std::numeric_limits<value_type>::max())
391 for (
typename std::vector<term_type>::const_iterator it =
m_model->objective().terms().begin(), ite =
m_model->objective().terms().end(); it != ite; ++it)
393 if (it->coefficient() > 0)
399 if (
m_boundBigM == std::numeric_limits<value_type>::max())
405template <
typename T,
typename V>
422template <
typename T,
typename V>
428 for (
unsigned int i = 0, ie =
m_model->numVariables(); i < ie; ++i)
430 for (
typename std::vector<term_type>::const_iterator it =
m_model->objective().terms().begin(), ite =
m_model->objective().terms().end(); it != ite; ++it)
433template <
typename T,
typename V>
440 unsigned int numArcs =
m_model->constraints().size();
444 for (
typename std::vector<constraint_type>::iterator it =
m_model->constraints().begin(), ite =
m_model->constraints().end(); it != ite; ++it)
446 constraint_type& constr = *it;
450 for (
typename std::vector<constraint_type>::const_iterator it =
m_model->constraints().begin(), ite =
m_model->constraints().end(); it != ite; ++it)
452 constraint_type
const& constr = *it;
454 variable_type xi = (vTerm[0].coefficient() > 0)? vTerm[0].variable() : vTerm[1].variable();
455 variable_type xj = (vTerm[0].coefficient() > 0)? vTerm[1].variable() : vTerm[0].variable();
462template <
typename T,
typename V>
469 unsigned int numArcs = 0;
470 for (
unsigned int i = 0, ie =
m_model->numVariables(); i < ie; ++i)
472 value_type lowerBound =
m_model->variableLowerBound(variable_type(i));
473 value_type upperBound =
m_model->variableUpperBound(variable_type(i));
476 if (upperBound != std::numeric_limits<value_type>::max())
479 if (!countArcs && numArcs)
483 node_type addlNode =
m_graph.addNode();
484 value_type addlWeight = 0;
485 for (
typename std::vector<term_type>::const_iterator it =
m_model->objective().terms().begin(), ite =
m_model->objective().terms().end(); it != ite; ++it)
486 addlWeight -= it->coefficient();
491 for (
unsigned int i = 0, ie =
m_model->numVariables(); i < ie; ++i)
493 value_type lowerBound =
m_model->variableLowerBound(variable_type(i));
494 value_type upperBound =
m_model->variableUpperBound(variable_type(i));
501 if (upperBound != std::numeric_limits<value_type>::max())
507template <
typename T,
typename V>
519 arc_type arc =
m_graph.addArc(xi, xj);
526 arc_type arc =
m_graph.addArc(xj, xi);
536template <
typename T,
typename V>
540 value_type addlValue = 0;
544 for (
typename std::vector<value_type>::iterator it =
m_model->variableSolutions().begin(), ite =
m_model->variableSolutions().end(); it != ite; ++it, ++i)
552template <
typename T,
typename V>
589template <
typename T,
typename V>
590class CapacityScaling :
public MinCostFlowSolver<T, V>
600 typedef lemon::CapacityScaling<
typename dualsolver_type::graph_type,
638 typename alg_type::ProblemType status = alg.resetParams()
649 case alg_type::OPTIMAL:
652 case alg_type::INFEASIBLE:
655 case alg_type::UNBOUNDED:
685template <
typename T,
typename V>
696 typedef lemon::CostScaling<
typename dualsolver_type::graph_type,
703 CostScaling(
typename alg_type::Method method = alg_type::PARTIAL_AUGMENT,
int factor = 16)
736 typename alg_type::ProblemType status = alg.resetParams()
747 case alg_type::OPTIMAL:
750 case alg_type::INFEASIBLE:
753 case alg_type::UNBOUNDED:
785template <
typename T,
typename V>
796 typedef lemon::NetworkSimplex<
typename dualsolver_type::graph_type,
834 typename alg_type::ProblemType status = alg.resetParams()
845 case alg_type::OPTIMAL:
848 case alg_type::INFEASIBLE:
851 case alg_type::UNBOUNDED:
881template <
typename T,
typename V>
892 typedef lemon::CycleCanceling<
typename dualsolver_type::graph_type,
930 typename alg_type::ProblemType status = alg.resetParams()
941 case alg_type::OPTIMAL:
944 case alg_type::INFEASIBLE:
947 case alg_type::UNBOUNDED:
#define limboAssertMsg(condition, args...)
custom assertion with message
#define limboAssert(condition)
custom assertion without message
Basic utilities such as variables and linear expressions in solvers.
Capacity scaling algorithm for min-cost flow.
void copy(CapacityScaling const &rhs)
copy object
MinCostFlowSolver< T, V > base_type
base type
base_type::dualsolver_type dualsolver_type
dual min-cost flow solver type
int m_factor
scaling factor for the algorithm
virtual SolverProperty operator()(dualsolver_type *d)
API to run min-cost flow solver.
CapacityScaling(CapacityScaling const &rhs)
copy constructor
CapacityScaling & operator=(CapacityScaling const &rhs)
assignment
lemon::CapacityScaling< typename dualsolver_type::graph_type, value_type, value_type > alg_type
algorithm type
CapacityScaling(int factor=4)
constructor
Cost scaling algorithm for min-cost flow.
void copy(CostScaling const &rhs)
copy object
int m_factor
scaling factor for the algorithm
virtual SolverProperty operator()(dualsolver_type *d)
API to run min-cost flow solver.
CostScaling(CostScaling const &rhs)
copy constructor
base_type::dualsolver_type dualsolver_type
dual min-cost flow solver type
alg_type::Method m_method
PUSH, AUGMENT, PARTIAL_AUGMENT.
lemon::CostScaling< typename dualsolver_type::graph_type, value_type, value_type > alg_type
algorithm type
MinCostFlowSolver< T, V > base_type
base type
CostScaling(typename alg_type::Method method=alg_type::PARTIAL_AUGMENT, int factor=16)
constructor
CostScaling & operator=(CostScaling const &rhs)
assignment
Cycle canceling algorithm for min-cost flow.
CycleCanceling(CycleCanceling const &rhs)
copy constructor
CycleCanceling(typename alg_type::Method method=alg_type::CANCEL_AND_TIGHTEN)
constructor
MinCostFlowSolver< T, V > base_type
base type
CycleCanceling & operator=(CycleCanceling const &rhs)
assignment
void copy(CycleCanceling const &rhs)
copy object
base_type::dualsolver_type dualsolver_type
dual min-cost flow solver type
virtual SolverProperty operator()(dualsolver_type *d)
API to run min-cost flow solver.
lemon::CycleCanceling< typename dualsolver_type::graph_type, value_type, value_type > alg_type
algorithm type
alg_type::Method m_method
method for the algorithm, SIMPLE_CYCLE_CANCELING, MINIMUM_MEAN_CYCLE_CANCELING, CANCEL_AND_TIGHTEN
LP solved with min-cost flow. A better implementation of limbo::solvers::lpmcf::LpDualMcf.
void buildGraph()
build dual min-cost flow graph
value_type m_diffBigM
a big number for infinity for differential constraints
LinearModel< T, V > model_type
linear model type for the problem
arc_value_map_type m_mUpper
upper bound of flow, arc capacity in min-cost flow
DualMinCostFlow & operator=(DualMinCostFlow const &rhs)
assignment, forbidden
node_pot_map_type m_mPotential
dual solution of min-cost flow, which is the solution of LP
SolverProperty operator()(solver_type *solver=NULL)
API to run the algorithm.
~DualMinCostFlow()
destructor
value_type m_totalFlowCost
total cost after solving
arc_flow_map_type m_mFlow
solution of min-cost flow, which is the dual solution of LP
model_type * m_model
model for the problem
arc_cost_map_type const & costMap() const
graph_type const & graph() const
value_type boundBigM() const
void mapObjective2Graph()
map variables and the objective to graph nodes
void applySolution()
apply solutions to model
void addArcForDiffConstraint(node_type xi, node_type xj, value_type cij, value_type bigM)
generalized method to add an arc for differential constraint , resolve negative arc costs by arc reve...
SolverProperty solve(solver_type *solver)
kernel function to solve the problem
void printGraph(bool writeSol) const
print graph
value_type diffBigM() const
node_value_map_type m_mSupply
node supply in min-cost flow
unsigned int mapDiffConstraint2Graph(bool countArcs)
map differential constraints to graph arcs
value_type m_boundBigM
a big number for infinity for bound constraints
node_pot_map_type & potentialMap()
void setTotalFlowCost(value_type cost)
DualMinCostFlow(DualMinCostFlow const &rhs)
copy constructor, forbidden
value_type totalFlowCost() const
unsigned int mapBoundConstraint2Graph(bool countArcs)
map bound constraints to graph arcs
void setBoundBigM(value_type v)
set big M as a large number for bound constraints
node_value_map_type const & supplyMap() const
arc_flow_map_type & flowMap()
graph_type m_graph
input graph
value_type m_reversedArcFlowCost
normalized flow cost of overall reversed arcs to resolve negative arc cost, to get total flow cost of...
DualMinCostFlow(model_type *model)
constructor
void prepare()
prepare data like big M
arc_value_map_type const & upperMap() const
arc_cost_map_type m_mCost
arc cost in min-cost flow
void setDiffBigM(value_type v)
set big M as a large number for differential constraints
value_type totalCost() const
coefficient_value_type rightHandSide() const
expression_type const & expression() const
void normalize(char s)
normalize sense
std::vector< term_type > const & terms() const
model to describe an optimization problem
V variable_value_type
V variable.
VariableProperty< variable_value_type > property_type
variable property type
Variable< coefficient_value_type > variable_type
variable type
T coefficient_value_type
T coefficient.
LinearConstraint< coefficient_value_type > constraint_type
constraint type
LinearExpression< coefficient_value_type > expression_type
expression type
LinearTerm< coefficient_value_type > term_type
term type
A base class of min-cost flow solver.
DualMinCostFlow< coefficient_value_type, variable_value_type > dualsolver_type
MinCostFlowSolver & operator=(MinCostFlowSolver const &rhs)
assignment
MinCostFlowSolver()
constructor
MinCostFlowSolver(MinCostFlowSolver const &rhs)
copy constructor
virtual ~MinCostFlowSolver()
destructor
void copy(MinCostFlowSolver const &)
copy object
virtual SolverProperty operator()(dualsolver_type *d)=0
API to run min-cost flow solver.
Network simplex algorithm for min-cost flow.
lemon::NetworkSimplex< typename dualsolver_type::graph_type, value_type, value_type > alg_type
algorithm type
NetworkSimplex(typename alg_type::PivotRule pivotRule=alg_type::BLOCK_SEARCH)
constructor
MinCostFlowSolver< T, V > base_type
base type
alg_type::PivotRule m_pivotRule
pivot rule for the algorithm, FIRST_ELIGIBLE, BEST_ELIGIBLE, BLOCK_SEARCH, CANDIDATE_LIST,...
void copy(NetworkSimplex const &rhs)
copy object
NetworkSimplex & operator=(NetworkSimplex const &rhs)
assignment
virtual SolverProperty operator()(dualsolver_type *d)
API to run min-cost flow solver.
base_type::dualsolver_type dualsolver_type
dual min-cost flow solver type
NetworkSimplex(NetworkSimplex const &rhs)
copy constructor
namespace for Limbo.Solvers
SolverProperty
Some enums used in solver.
@ OPTIMAL
optimally solved
@ INFEASIBLE
the model is infeasible
@ UNBOUNDED
the model is unbounded
std::iterator_traits< Iterator >::value_type max(Iterator first, Iterator last)
get max of an array
int limboPrint(MessageType m, const char *format,...)
formatted print with prefix
T lowest()
generic function to get lowest value of numbers