7#ifndef LIMBO_SOLVERS_MINCOSTFLOW_H
8#define LIMBO_SOLVERS_MINCOSTFLOW_H
10#include <lemon/smart_graph.h>
11#include <lemon/network_simplex.h>
12#include <lemon/cost_scaling.h>
13#include <lemon/capacity_scaling.h>
14#include <lemon/cycle_canceling.h>
15#include <lemon/lgf_writer.h>
29template <
typename T,
typename V>
31template <
typename T,
typename V>
33template <
typename T,
typename V>
35template <
typename T,
typename V>
37template <
typename T,
typename V>
59template <
typename T,
typename V>
68 typedef variable_value_type value_type;
75 typedef lemon::SmartDigraph graph_type;
76 typedef graph_type::Node node_type;
77 typedef graph_type::Arc arc_type;
78 typedef graph_type::NodeMap<value_type> node_value_map_type;
79 typedef graph_type::NodeMap<std::string> node_name_map_type;
80 typedef graph_type::ArcMap<std::string> arc_name_map_type;
81 typedef graph_type::ArcMap<value_type> arc_value_map_type;
82 typedef graph_type::ArcMap<value_type> arc_cost_map_type;
83 typedef graph_type::ArcMap<value_type> arc_flow_map_type;
84 typedef graph_type::NodeMap<value_type> node_pot_map_type;
112 return solve(solver);
116 graph_type
const&
graph()
const;
118 arc_value_map_type
const&
lowerMap()
const;
120 arc_value_map_type
const&
upperMap()
const;
122 arc_cost_map_type
const&
costMap()
const;
124 node_value_map_type
const&
supplyMap()
const;
173template <
typename T,
typename V>
178template <
typename T,
typename V>
183template <
typename T,
typename V>
188template <
typename T,
typename V>
193template <
typename T,
typename V>
198template <
typename T,
typename V>
203template <
typename T,
typename V>
208template <
typename T,
typename V>
213template <
typename T,
typename V>
218template <
typename T,
typename V>
223template <
typename T,
typename V>
229 node_name_map_type nodeNameMap (
m_graph);
230 for (
unsigned int i = 0, ie =
m_model->constraints().size(); i < ie; ++i)
231 nodeNameMap[
m_graph.nodeFromId(i)] =
m_model->constraintNames().at(i);
234 arc_name_map_type arcNameMap (
m_graph);
235 for (
unsigned int i = 0, ie =
m_model->numVariables(); i < ie; ++i)
236 arcNameMap[
m_graph.arcFromId(i)] =
m_model->variableName(variable_type(i));
239 lemon::DigraphWriter<graph_type> writer(
m_graph,
"debug.lgf");
241 .nodeMap(
"name", nodeNameMap)
242 .arcMap(
"name", arcNameMap)
251template <
typename T,
typename V>
254 bool defaultSolver =
false;
259 defaultSolver =
true;
263 if (
m_model->numVariables() == 0)
271#ifdef DEBUG_MINCOSTFLOW
274 coefficient_value_type totalSupply = 0;
275 for (graph_type::NodeIt it (
m_graph); it != lemon::INVALID; ++it)
284#ifdef DEBUG_MINCOSTFLOW
293template <
typename T,
typename V>
298 unsigned int numNodes = 0;
299 for (
typename std::vector<constraint_type>::const_iterator it =
m_model->constraints().begin(), ite =
m_model->constraints().end(); it != ite; ++it)
302 limboAssertMsg(it->sense() ==
'=',
"only support equality constraints %s",
m_model->constraintName(*it).c_str());
308 coefficient_value_type totalSupply = 0;
309 m_graph.reserveNode(numNodes+1);
310 for (
unsigned int i = 0, ie = numNodes+1; i < ie; ++i)
313 node_type st =
m_graph.nodeFromId(numNodes);
319 std::vector<std::pair<unsigned int, unsigned int> > vVar2Constr (
m_model->numVariables(), std::make_pair(std::numeric_limits<unsigned int>::max(), std::numeric_limits<unsigned int>::max()));
320 unsigned int constrIndex = 0;
321 for (
typename std::vector<constraint_type>::const_iterator it =
m_model->constraints().begin(), ite =
m_model->constraints().end(); it != ite; ++it)
323 constraint_type constr = *it;
329 for (
typename std::vector<term_type>::const_iterator itt = constr.
expression().
terms().begin(), itte = constr.
expression().
terms().end(); itt != itte; ++itt)
331 term_type
const& term = *itt;
332 std::pair<unsigned int, unsigned int>
const& value = vVar2Constr[term.
variable().
id()];
336 if (value.first != std::numeric_limits<unsigned int>::max())
341 else if (value.second != std::numeric_limits<unsigned int>::max())
349 if (value.second != std::numeric_limits<unsigned int>::max())
354 else if (value.first != std::numeric_limits<unsigned int>::max())
365 for (
typename std::vector<term_type>::const_iterator itt = constr.
expression().
terms().begin(), itte = constr.
expression().
terms().end(); itt != itte; ++itt)
367 term_type
const& term = *itt;
368 std::pair<unsigned int, unsigned int>& value = vVar2Constr[term.
variable().
id()];
371 limboAssertMsg(value.first == std::numeric_limits<unsigned int>::max(),
372 "variable %s appears in more than 1 constraint with coefficient 1",
m_model->variableName(term.
variable()).c_str());
373 value.first = constrIndex;
377 limboAssertMsg(value.second == std::numeric_limits<unsigned int>::max(),
378 "variable %s appears in more than 1 constraint with coefficient -1",
m_model->variableName(term.
variable()).c_str());
379 value.second = constrIndex;
394 m_graph.reserveArc(vVar2Constr.size());
396 unsigned int var = 0;
397 for (std::vector<std::pair<unsigned int, unsigned int> >::const_iterator it = vVar2Constr.begin(), ite = vVar2Constr.end(); it != ite; ++it, ++var)
399 unsigned int constrSrc = it->first;
400 unsigned int constrTgt = it->second;
403 if (constrSrc == std::numeric_limits<unsigned int>::max())
407 else if (constrTgt == std::numeric_limits<unsigned int>::max())
417#ifdef DEBUG_MINCOSTFLOW
425template <
typename T,
typename V>
428 for (
typename std::vector<term_type>::const_iterator it = obj.
terms().begin(), ite = obj.
terms().end(); it != ite; ++it)
430 term_type
const& term = *it;
431 switch (
m_model->optimizeType())
445template <
typename T,
typename V>
449 for (
typename std::vector<value_type>::iterator it =
m_model->variableSolutions().begin(), ite =
m_model->variableSolutions().end(); it != ite; ++it, ++i)
456template <
typename T,
typename V>
493template <
typename T,
typename V>
504 typedef lemon::CapacityScaling<
typename primalsolver_type::graph_type,
542 typename alg_type::ProblemType status = alg.resetParams()
553 case alg_type::OPTIMAL:
556 case alg_type::INFEASIBLE:
559 case alg_type::UNBOUNDED:
589template <
typename T,
typename V>
600 typedef lemon::CostScaling<
typename primalsolver_type::graph_type,
607 CostScaling(
typename alg_type::Method method = alg_type::PARTIAL_AUGMENT,
int factor = 16)
640 typename alg_type::ProblemType status = alg.resetParams()
651 case alg_type::OPTIMAL:
654 case alg_type::INFEASIBLE:
657 case alg_type::UNBOUNDED:
689template <
typename T,
typename V>
700 typedef lemon::NetworkSimplex<
typename primalsolver_type::graph_type,
738 typename alg_type::ProblemType status = alg.resetParams()
749 case alg_type::OPTIMAL:
752 case alg_type::INFEASIBLE:
755 case alg_type::UNBOUNDED:
785template <
typename T,
typename V>
796 typedef lemon::CycleCanceling<
typename primalsolver_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:
#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
base_type::primalsolver_type primalsolver_type
dual min-cost flow solver type
virtual SolverProperty operator()(primalsolver_type *d)
API to run min-cost flow solver.
MinCostFlowSolver< T, V > base_type
base type
int m_factor
scaling factor for the algorithm
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
CostScaling(CostScaling const &rhs)
copy constructor
alg_type::Method m_method
PUSH, AUGMENT, PARTIAL_AUGMENT.
base_type::primalsolver_type primalsolver_type
dual min-cost flow solver type
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
virtual SolverProperty operator()(primalsolver_type *d)
API to run min-cost flow solver.
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
base_type::primalsolver_type primalsolver_type
dual min-cost flow solver type
CycleCanceling & operator=(CycleCanceling const &rhs)
assignment
void copy(CycleCanceling const &rhs)
copy object
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
virtual SolverProperty operator()(primalsolver_type *d)
API to run min-cost flow solver.
coefficient_value_type rightHandSide() const
void scale(coefficient_value_type factor)
scale constraint by a scaling factor
expression_type const & expression() const
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
coefficient_value_type coefficient() const
variable_type const & variable() const
LP solved with min-cost flow.
graph_type const & graph() const
SolverProperty operator()(solver_type *solver=NULL)
API to run the algorithm.
node_pot_map_type & potentialMap()
arc_cost_map_type const & costMap() const
MinCostFlow(model_type *model)
constructor
arc_value_map_type m_mUpper
upper bound of flow, arc capacity in min-cost flow
void applySolution()
apply solutions to model
arc_value_map_type const & upperMap() const
arc_flow_map_type & flowMap()
MinCostFlow & operator=(MinCostFlow const &rhs)
assignment, forbidden
void setTotalFlowCost(value_type cost)
arc_cost_map_type m_mCost
arc cost in min-cost flow
MinCostFlow(MinCostFlow const &rhs)
copy constructor, forbidden
SolverProperty solve(solver_type *solver)
kernel function to solve the problem
void buildGraph()
build min-cost flow graph
node_pot_map_type m_mPotential
solution of min-cost flow, which is the dual solution of LP
value_type m_totalFlowCost
total cost after solving
value_type totalCost() const
value_type totalFlowCost() const
node_value_map_type const & supplyMap() const
arc_value_map_type m_mLower
lower bound of flow, usually zero
node_value_map_type m_mSupply
node supply in min-cost flow
arc_flow_map_type m_mFlow
solution of min-cost flow, which is the solution of LP
arc_value_map_type const & lowerMap() const
model_type * m_model
model for the problem
graph_type m_graph
input graph
void printGraph(bool writeSol) const
print graph
void setObjective(expression_type const &obj)
set objective, support incremental set
LinearModel< T, V > model_type
linear model type for the problem
A base class of min-cost flow solver.
MinCostFlow< coefficient_value_type, variable_value_type > primalsolver_type
MinCostFlowSolver & operator=(MinCostFlowSolver const &rhs)
assignment
MinCostFlowSolver()
constructor
MinCostFlowSolver(MinCostFlowSolver const &rhs)
copy constructor
virtual ~MinCostFlowSolver()
destructor
virtual SolverProperty operator()(primalsolver_type *d)=0
API to run min-cost flow solver.
void copy(MinCostFlowSolver const &)
copy object
Network simplex algorithm for min-cost flow.
virtual SolverProperty operator()(primalsolver_type *d)
API to run min-cost flow solver.
base_type::primalsolver_type primalsolver_type
dual min-cost flow solver type
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
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