Limbo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MinCostFlow.h
Go to the documentation of this file.
1 
7 #ifndef LIMBO_SOLVERS_MINCOSTFLOW_H
8 #define LIMBO_SOLVERS_MINCOSTFLOW_H
9 
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>
16 
17 #include <limbo/solvers/Solvers.h>
18 
20 namespace limbo
21 {
23 namespace solvers
24 {
25 
26 // forward declaration
27 // Only CapacityScaling supports real value costs.
28 // All other methods require integer costs.
29 template <typename T, typename V>
30 class MinCostFlowSolver;
31 template <typename T, typename V>
32 class CapacityScaling;
33 template <typename T, typename V>
34 class CostScaling;
35 template <typename T, typename V>
36 class NetworkSimplex;
37 template <typename T, typename V>
38 class CycleCanceling;
39 
59 template <typename T, typename V>
61 {
62  public:
66  typedef typename model_type::coefficient_value_type coefficient_value_type;
67  typedef typename model_type::variable_value_type variable_value_type;
68  typedef variable_value_type value_type; // use only one kind of value type
72  typedef typename model_type::term_type term_type;
74 
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; // potential of each node
85 
88 
91  MinCostFlow(model_type* model)
92  : m_model(model)
93  , m_graph()
94  , m_mLower(m_graph)
95  , m_mUpper(m_graph)
96  , m_mCost(m_graph)
98  , m_totalFlowCost(std::numeric_limits<typename MinCostFlow<T, V>::value_type>::max())
99  , m_mFlow(m_graph)
101  {
102  }
105  {
106  }
107 
110  SolverProperty operator()(solver_type* solver = NULL)
111  {
112  return solve(solver);
113  }
114 
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;
126  arc_flow_map_type& flowMap();
128  node_pot_map_type& potentialMap();
130  value_type totalFlowCost() const;
132  void setTotalFlowCost(value_type cost);
134  value_type totalCost() const;
135 
140  void printGraph(bool writeSol) const;
142  protected:
145  MinCostFlow(MinCostFlow const& rhs);
148  MinCostFlow& operator=(MinCostFlow const& rhs);
149 
152  SolverProperty solve(solver_type* solver);
154  void buildGraph();
156  void setObjective(expression_type const& obj);
158  void applySolution();
159 
160  model_type* m_model;
161 
162  graph_type m_graph;
163  arc_value_map_type m_mLower;
164  arc_value_map_type m_mUpper;
165  arc_cost_map_type m_mCost;
166  node_value_map_type m_mSupply;
167  value_type m_totalFlowCost;
168 
169  arc_flow_map_type m_mFlow;
170  node_pot_map_type m_mPotential;
171 };
172 
173 template <typename T, typename V>
174 typename MinCostFlow<T, V>::graph_type const& MinCostFlow<T, V>::graph() const
175 {
176  return m_graph;
177 }
178 template <typename T, typename V>
179 typename MinCostFlow<T, V>::arc_value_map_type const& MinCostFlow<T, V>::lowerMap() const
180 {
181  return m_mLower;
182 }
183 template <typename T, typename V>
184 typename MinCostFlow<T, V>::arc_value_map_type const& MinCostFlow<T, V>::upperMap() const
185 {
186  return m_mUpper;
187 }
188 template <typename T, typename V>
189 typename MinCostFlow<T, V>::arc_cost_map_type const& MinCostFlow<T, V>::costMap() const
190 {
191  return m_mCost;
192 }
193 template <typename T, typename V>
194 typename MinCostFlow<T, V>::node_value_map_type const& MinCostFlow<T, V>::supplyMap() const
195 {
196  return m_mSupply;
197 }
198 template <typename T, typename V>
199 typename MinCostFlow<T, V>::arc_flow_map_type& MinCostFlow<T, V>::flowMap()
200 {
201  return m_mFlow;
202 }
203 template <typename T, typename V>
204 typename MinCostFlow<T, V>::node_pot_map_type& MinCostFlow<T, V>::potentialMap()
205 {
206  return m_mPotential;
207 }
208 template <typename T, typename V>
209 typename MinCostFlow<T, V>::value_type MinCostFlow<T, V>::totalFlowCost() const
210 {
211  return m_totalFlowCost;
212 }
213 template <typename T, typename V>
214 void MinCostFlow<T, V>::setTotalFlowCost(typename MinCostFlow<T, V>::value_type cost)
215 {
216  m_totalFlowCost = cost;
217 }
218 template <typename T, typename V>
219 typename MinCostFlow<T, V>::value_type MinCostFlow<T, V>::totalCost() const
220 {
221  return totalFlowCost();
222 }
223 template <typename T, typename V>
224 void MinCostFlow<T, V>::printGraph(bool writeSol) const
225 {
226  if (writeSol)
227  limboPrint(kDEBUG, "totalFlowCost = %ld, totalCost = %ld\n", (long)totalFlowCost(), (long)totalCost());
228 
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);
232  nodeNameMap[m_graph.nodeFromId(m_graph.maxNodeId())] = "st";
233 
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));
237 
238  // dump lgf file
239  lemon::DigraphWriter<graph_type> writer(m_graph, "debug.lgf");
240  writer.nodeMap("supply", m_mSupply)
241  .nodeMap("name", nodeNameMap)
242  .arcMap("name", arcNameMap)
243  .arcMap("capacity_lower", m_mLower)
244  .arcMap("capacity_upper", m_mUpper)
245  .arcMap("cost", m_mCost);
246  if (writeSol)
247  writer.nodeMap("potential", m_mPotential)
248  .arcMap("flow", m_mFlow);
249  writer.run();
250 }
251 template <typename T, typename V>
253 {
254  bool defaultSolver = false;
255  // use default solver if NULL
256  if (solver == NULL)
257  {
259  defaultSolver = true;
260  }
261 
262  // skip empty problem
263  if (m_model->numVariables() == 0)
264  return OPTIMAL;
265 
266  // build graph if no nodes, I know in corner cases it may be called repeatedly
267  // but this seems to be the best way
268  if (m_graph.nodeNum() == 0)
269  buildGraph();
270  setObjective(m_model->objective());
271 #ifdef DEBUG_MINCOSTFLOW
272  printGraph(false);
273  // total supply must be zero
274  coefficient_value_type totalSupply = 0;
275  for (graph_type::NodeIt it (m_graph); it != lemon::INVALID; ++it)
276  totalSupply += m_mSupply[it];
277  limboAssert(totalSupply == 0);
278 #endif
279  // solve min-cost flow problem
280  SolverProperty status = solver->operator()(this);
281  // apply solution
282  applySolution();
283 
284 #ifdef DEBUG_MINCOSTFLOW
285  printGraph(true);
286 #endif
287 
288  if (defaultSolver)
289  delete solver;
290 
291  return status;
292 }
293 template <typename T, typename V>
295 {
296  // compute how many nodes
297  // regard equality constraints as nodes except for s and t
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)
300  {
301  // assume only equality constraints
302  limboAssertMsg(it->sense() == '=', "only support equality constraints %s", m_model->constraintName(*it).c_str());
303  // equality constraints
304  numNodes += 1;
305  }
306 
307  // construct nodes
308  coefficient_value_type totalSupply = 0;
309  m_graph.reserveNode(numNodes+1); // additional nodes for s and t
310  for (unsigned int i = 0, ie = numNodes+1; i < ie; ++i)
311  m_graph.addNode();
312  // node st
313  node_type st = m_graph.nodeFromId(numNodes);
314 
315  // a map record arc to its two nodes
316  // arc id, source node id, target node id
317  // variable id, constraint id positive, constraint id negative
318  // I assume vVar2Constr sorts according to variable id
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)
322  {
323  constraint_type constr = *it;
324  // equality constraints
325  //if (constr.sense() == '=')
326  {
327  // whether need to inverse the sign of the constraint
328  // only need to check the first found term
329  for (typename std::vector<term_type>::const_iterator itt = constr.expression().terms().begin(), itte = constr.expression().terms().end(); itt != itte; ++itt)
330  {
331  term_type const& term = *itt;
332  std::pair<unsigned int, unsigned int> const& value = vVar2Constr[term.variable().id()];
333  if (term.coefficient() == 1)
334  {
335  // I want value.first is not set
336  if (value.first != std::numeric_limits<unsigned int>::max())
337  {
338  constr.scale(-1);
339  break;
340  }
341  else if (value.second != std::numeric_limits<unsigned int>::max())
342  {
343  break;
344  }
345  }
346  else if (term.coefficient() == -1)
347  {
348  // I want value.first is not set
349  if (value.second != std::numeric_limits<unsigned int>::max())
350  {
351  constr.scale(-1);
352  break;
353  }
354  else if (value.first != std::numeric_limits<unsigned int>::max())
355  {
356  break;
357  }
358  }
359  else
360  {
361  limboAssertMsg(0, "unsupported coefficient %g in constraint %d\n", double(term.coefficient()), constr.id());
362  }
363  }
364  // record map
365  for (typename std::vector<term_type>::const_iterator itt = constr.expression().terms().begin(), itte = constr.expression().terms().end(); itt != itte; ++itt)
366  {
367  term_type const& term = *itt;
368  std::pair<unsigned int, unsigned int>& value = vVar2Constr[term.variable().id()];
369  if (term.coefficient() == 1)
370  {
372  "variable %s appears in more than 1 constraint with coefficient 1", m_model->variableName(term.variable()).c_str());
373  value.first = constrIndex;
374  }
375  else if (term.coefficient() == -1)
376  {
378  "variable %s appears in more than 1 constraint with coefficient -1", m_model->variableName(term.variable()).c_str());
379  value.second = constrIndex;
380  }
381  }
382  // compute supply
383  // since here we know whether this constraint is inversed
384  m_mSupply[m_graph.nodeFromId(constrIndex)] = constr.rightHandSide();
385  totalSupply += constr.rightHandSide();
386  // next cosntraint
387  ++constrIndex;
388  }
389  }
390  // supply for s and t
391  m_mSupply[st] = -totalSupply;
392 
393  // construct arcs
394  m_graph.reserveArc(vVar2Constr.size());
395  // I assume vVar2Constr sorts according to variable id
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)
398  {
399  unsigned int constrSrc = it->first;
400  unsigned int constrTgt = it->second;
401 
402  arc_type arc;
403  if (constrSrc == std::numeric_limits<unsigned int>::max()) // from s
404  {
405  arc = m_graph.addArc(st, m_graph.nodeFromId(constrTgt));
406  }
407  else if (constrTgt == std::numeric_limits<unsigned int>::max()) // to t
408  {
409  arc = m_graph.addArc(m_graph.nodeFromId(constrSrc), st);
410  }
411  else
412  {
413  arc = m_graph.addArc(m_graph.nodeFromId(constrSrc), m_graph.nodeFromId(constrTgt));
414  }
415  m_mLower[arc] = m_model->variableLowerBound(m_model->variable(var));
416  m_mUpper[arc] = m_model->variableUpperBound(m_model->variable(var));
417 #ifdef DEBUG_MINCOSTFLOW
418  limboAssert(arc == m_graph.arcFromId(var));
419 #endif
420  }
421 
422  // construct cost map
423  // everytime solver is called
424 }
425 template <typename T, typename V>
427 {
428  for (typename std::vector<term_type>::const_iterator it = obj.terms().begin(), ite = obj.terms().end(); it != ite; ++it)
429  {
430  term_type const& term = *it;
431  switch (m_model->optimizeType())
432  {
433  case MIN:
434  m_mCost[m_graph.arcFromId(term.variable().id())] = term.coefficient();
435  break;
436  case MAX:
437  m_mCost[m_graph.arcFromId(term.variable().id())] = -term.coefficient();
438  break;
439  default:
440  limboAssertMsg(0, "Unknown optimization type");
441  break;
442  }
443  }
444 }
445 template <typename T, typename V>
447 {
448  unsigned int i = 0;
449  for (typename std::vector<value_type>::iterator it = m_model->variableSolutions().begin(), ite = m_model->variableSolutions().end(); it != ite; ++it, ++i)
450  *it = m_mFlow[m_graph.arcFromId(i)];
451 }
452 
456 template <typename T, typename V>
457 class MinCostFlowSolver
458 {
459  public:
462 
468  {
469  copy(rhs);
470  }
474  {
475  if (this != &rhs)
476  copy(rhs);
477  return *this;
478  }
480  virtual ~MinCostFlowSolver() {}
481 
484  virtual SolverProperty operator()(primalsolver_type* d) = 0;
485  protected:
487  void copy(MinCostFlowSolver const& /*rhs*/) {}
488 };
489 
493 template <typename T, typename V>
494 class CapacityScaling : public MinCostFlowSolver<T, V>
495 {
496  public:
498  typedef T value_type;
504  typedef lemon::CapacityScaling<typename primalsolver_type::graph_type,
505  value_type,
506  value_type> alg_type;
507 
510  CapacityScaling(int factor = 4)
511  : base_type()
512  , m_factor(factor)
513  {
514  }
518  : CapacityScaling::base_type(rhs)
519  {
520  copy(rhs);
521  }
525  {
526  if (this != &rhs)
527  {
528  this->base_type::operator=(rhs);
529  copy(rhs);
530  }
531  return *this;
532  }
533 
536  virtual SolverProperty operator()(primalsolver_type* d)
537  {
538  // 1. choose algorithm
539  alg_type alg (d->graph());
540 
541  // 2. run
542  typename alg_type::ProblemType status = alg.resetParams()
543  .lowerMap(d->lowerMap())
544  .upperMap(d->upperMap())
545  .costMap(d->costMap())
546  .supplyMap(d->supplyMap())
547  .run(m_factor);
548 
549  // 3. check results
550  SolverProperty solverStatus;
551  switch (status)
552  {
553  case alg_type::OPTIMAL:
554  solverStatus = OPTIMAL;
555  break;
557  solverStatus = INFEASIBLE;
558  break;
559  case alg_type::UNBOUNDED:
560  solverStatus = UNBOUNDED;
561  break;
562  default:
563  limboAssertMsg(0, "unknown status");
564  }
565 
566  // 4. apply results
567  // get dual solution of LP, which is the flow of min-cost flow, skip this if not necessary
568  alg.flowMap(d->flowMap());
569  // get solution of LP, which is the dual solution of min-cost flow
570  alg.potentialMap(d->potentialMap());
571  // set total cost of min-cost flow
572  d->setTotalFlowCost(alg.totalCost());
573 
574  return solverStatus;
575  }
576  protected:
578  void copy(CapacityScaling const& rhs)
579  {
580  m_factor = rhs.m_factor;
581  }
582 
583  int m_factor;
584 };
585 
589 template <typename T, typename V>
590 class CostScaling : public MinCostFlowSolver<T, V>
591 {
592  public:
594  typedef T value_type;
600  typedef lemon::CostScaling<typename primalsolver_type::graph_type,
601  value_type,
602  value_type> alg_type;
603 
607  CostScaling(typename alg_type::Method method = alg_type::PARTIAL_AUGMENT, int factor = 16)
608  : base_type()
609  , m_method(method)
610  , m_factor(factor)
611  {
612  }
616  : base_type(rhs)
617  {
618  copy(rhs);
619  }
623  {
624  if (this != &rhs)
625  {
626  this->base_type::operator=(rhs);
627  copy(rhs);
628  }
629  return *this;
630  }
631 
634  virtual SolverProperty operator()(primalsolver_type* d)
635  {
636  // 1. choose algorithm
637  alg_type alg (d->graph());
638 
639  // 2. run
640  typename alg_type::ProblemType status = alg.resetParams()
641  .lowerMap(d->lowerMap())
642  .upperMap(d->upperMap())
643  .costMap(d->costMap())
644  .supplyMap(d->supplyMap())
645  .run(m_method, m_factor);
646 
647  // 3. check results
648  SolverProperty solverStatus;
649  switch (status)
650  {
651  case alg_type::OPTIMAL:
652  solverStatus = OPTIMAL;
653  break;
655  solverStatus = INFEASIBLE;
656  break;
657  case alg_type::UNBOUNDED:
658  solverStatus = UNBOUNDED;
659  break;
660  default:
661  limboAssertMsg(0, "unknown status");
662  }
663 
664  // 4. apply results
665  // get dual solution of LP, which is the flow of min-cost flow, skip this if not necessary
666  alg.flowMap(d->flowMap());
667  // get solution of LP, which is the dual solution of min-cost flow
668  alg.potentialMap(d->potentialMap());
669  // set total cost of min-cost flow
670  d->setTotalFlowCost(alg.totalCost());
671 
672  return solverStatus;
673  }
674  protected:
676  void copy(CostScaling const& rhs)
677  {
678  m_method = rhs.m_method;
679  m_factor = rhs.m_factor;
680  }
681 
682  typename alg_type::Method m_method;
683  int m_factor;
684 };
685 
689 template <typename T, typename V>
690 class NetworkSimplex : public MinCostFlowSolver<T, V>
691 {
692  public:
694  typedef T value_type;
700  typedef lemon::NetworkSimplex<typename primalsolver_type::graph_type,
701  value_type,
702  value_type> alg_type;
703 
706  NetworkSimplex(typename alg_type::PivotRule pivotRule = alg_type::BLOCK_SEARCH)
707  : base_type()
708  , m_pivotRule(pivotRule)
709  {
710  }
714  : base_type(rhs)
715  {
716  copy(rhs);
717  }
721  {
722  if (this != &rhs)
723  {
724  this->base_type::operator=(rhs);
725  copy(rhs);
726  }
727  return *this;
728  }
729 
732  virtual SolverProperty operator()(primalsolver_type* d)
733  {
734  // 1. choose algorithm
735  alg_type alg (d->graph());
736 
737  // 2. run
738  typename alg_type::ProblemType status = alg.resetParams()
739  .lowerMap(d->lowerMap())
740  .upperMap(d->upperMap())
741  .costMap(d->costMap())
742  .supplyMap(d->supplyMap())
743  .run(m_pivotRule);
744 
745  // 3. check results
746  SolverProperty solverStatus;
747  switch (status)
748  {
749  case alg_type::OPTIMAL:
750  solverStatus = OPTIMAL;
751  break;
753  solverStatus = INFEASIBLE;
754  break;
755  case alg_type::UNBOUNDED:
756  solverStatus = UNBOUNDED;
757  break;
758  default:
759  limboAssertMsg(0, "unknown status");
760  }
761 
762  // 4. apply results
763  // get dual solution of LP, which is the flow of min-cost flow, skip this if not necessary
764  alg.flowMap(d->flowMap());
765  // get solution of LP, which is the dual solution of min-cost flow
766  alg.potentialMap(d->potentialMap());
767  // set total cost of min-cost flow
768  d->setTotalFlowCost(alg.totalCost());
769 
770  return solverStatus;
771  }
772  protected:
774  void copy(NetworkSimplex const& rhs)
775  {
776  m_pivotRule = rhs.m_pivotRule;
777  }
778 
779  typename alg_type::PivotRule m_pivotRule;
780 };
781 
785 template <typename T, typename V>
786 class CycleCanceling : public MinCostFlowSolver<T, V>
787 {
788  public:
790  typedef T value_type;
796  typedef lemon::CycleCanceling<typename primalsolver_type::graph_type,
797  value_type,
798  value_type> alg_type;
799 
802  CycleCanceling(typename alg_type::Method method = alg_type::CANCEL_AND_TIGHTEN)
803  : base_type()
804  , m_method(method)
805  {
806  }
810  : base_type(rhs)
811  {
812  copy(rhs);
813  }
817  {
818  if (this != &rhs)
819  {
820  this->operator=(rhs);
821  copy(rhs);
822  }
823  return *this;
824  }
825 
828  virtual SolverProperty operator()(primalsolver_type* d)
829  {
830  // 1. choose algorithm
831  alg_type alg (d->graph());
832 
833  // 2. run
834  typename alg_type::ProblemType status = alg.resetParams()
835  .lowerMap(d->lowerMap())
836  .upperMap(d->upperMap())
837  .costMap(d->costMap())
838  .supplyMap(d->supplyMap())
839  .run(m_method);
840 
841  // 3. check results
842  SolverProperty solverStatus;
843  switch (status)
844  {
845  case alg_type::OPTIMAL:
846  solverStatus = OPTIMAL;
847  break;
849  solverStatus = INFEASIBLE;
850  break;
851  case alg_type::UNBOUNDED:
852  solverStatus = UNBOUNDED;
853  break;
854  default:
855  limboAssertMsg(0, "unknown status");
856  }
857 
858  // 4. apply results
859  // get dual solution of LP, which is the flow of min-cost flow, skip this if not necessary
860  alg.flowMap(d->flowMap());
861  // get solution of LP, which is the dual solution of min-cost flow
862  alg.potentialMap(d->potentialMap());
863  // set total cost of min-cost flow
864  d->setTotalFlowCost(alg.totalCost());
865 
866  return solverStatus;
867  }
868  protected:
870  void copy(CycleCanceling const& rhs)
871  {
872  m_method = rhs.m_method;
873  }
874 
875  typename alg_type::Method m_method;
876 };
877 
878 
879 } // namespace solvers
880 } // namespace limbo
881 
882 #endif
graph_type const & graph() const
Definition: MinCostFlow.h:174
CostScaling & operator=(CostScaling const &rhs)
assignment
Definition: MinCostFlow.h:622
Capacity scaling algorithm for min-cost flow.
arc_flow_map_type m_mFlow
solution of min-cost flow, which is the solution of LP
Definition: MinCostFlow.h:169
CycleCanceling(CycleCanceling const &rhs)
copy constructor
Definition: MinCostFlow.h:809
void applySolution()
apply solutions to model
Definition: MinCostFlow.h:446
unsigned int id() const
Definition: Solvers.h:117
lemon::CapacityScaling< typename primalsolver_type::graph_type, value_type, value_type > alg_type
algorithm type
Definition: MinCostFlow.h:506
value_type totalFlowCost() const
Definition: MinCostFlow.h:209
void copy(CapacityScaling const &rhs)
copy object
maximize objective
Definition: Solvers.h:32
graph_type m_graph
input graph
Definition: MinCostFlow.h:162
Describe properties of a variable.
Definition: Solvers.h:72
int m_factor
scaling factor for the algorithm
void setTotalFlowCost(value_type cost)
Definition: MinCostFlow.h:214
LP solved with min-cost flow.
Definition: MinCostFlow.h:60
SolverProperty
Some enums used in solver.
Definition: Solvers.h:29
lemon::CycleCanceling< typename primalsolver_type::graph_type, value_type, value_type > alg_type
algorithm type
Definition: MinCostFlow.h:798
coefficient_value_type coefficient() const
Definition: Solvers.h:388
NetworkSimplex & operator=(NetworkSimplex const &rhs)
assignment
Definition: MinCostFlow.h:720
LinearModel< T, V > model_type
linear model type for the problem
Definition: MinCostFlow.h:64
virtual SolverProperty operator()(primalsolver_type *d)
API to run min-cost flow solver.
Definition: MinCostFlow.h:732
void buildGraph()
build min-cost flow graph
Definition: MinCostFlow.h:294
base_type::primalsolver_type primalsolver_type
dual min-cost flow solver type
Definition: MinCostFlow.h:502
arc_value_map_type const & upperMap() const
Definition: MinCostFlow.h:184
Basic utilities such as variables and linear expressions in solvers.
CycleCanceling(typename alg_type::Method method=alg_type::CANCEL_AND_TIGHTEN)
constructor
Definition: MinCostFlow.h:802
CapacityScaling(int factor=4)
constructor
Definition: MinCostFlow.h:510
MinCostFlowSolver< T, V > base_type
base type
Definition: MinCostFlow.h:792
Network simplex algorithm for min-cost flow.
value_type m_totalFlowCost
total cost after solving
Definition: MinCostFlow.h:167
node_pot_map_type & potentialMap()
Definition: MinCostFlow.h:204
virtual ~MinCostFlowSolver()
destructor
Definition: MinCostFlow.h:480
V variable_value_type
V variable.
Definition: Solvers.h:1166
T coefficient_value_type
T coefficient.
Definition: Solvers.h:1164
lemon::CostScaling< typename primalsolver_type::graph_type, value_type, value_type > alg_type
algorithm type
Definition: MinCostFlow.h:602
node_value_map_type m_mSupply
node supply in min-cost flow
Definition: MinCostFlow.h:166
alg_type::Method m_method
method for the algorithm, SIMPLE_CYCLE_CANCELING, MINIMUM_MEAN_CYCLE_CANCELING, CANCEL_AND_TIGHTEN ...
Describe linear constraint.
Definition: Solvers.h:78
arc_cost_map_type m_mCost
arc cost in min-cost flow
Definition: MinCostFlow.h:165
MinCostFlowSolver< T, V > base_type
base type
Definition: MinCostFlow.h:500
virtual SolverProperty operator()(primalsolver_type *d)
API to run min-cost flow solver.
Definition: MinCostFlow.h:536
CapacityScaling(CapacityScaling const &rhs)
copy constructor
Definition: MinCostFlow.h:517
void setObjective(expression_type const &obj)
set objective, support incremental set
Definition: MinCostFlow.h:426
SolverProperty operator()(solver_type *solver=NULL)
API to run the algorithm.
Definition: MinCostFlow.h:110
CycleCanceling & operator=(CycleCanceling const &rhs)
assignment
Definition: MinCostFlow.h:816
arc_flow_map_type & flowMap()
Definition: MinCostFlow.h:199
arc_value_map_type const & lowerMap() const
Definition: MinCostFlow.h:179
the model is infeasible
Definition: Solvers.h:37
value_type totalCost() const
Definition: MinCostFlow.h:219
virtual SolverProperty operator()(dualsolver_type *d)=0
API to run min-cost flow solver.
lemon::NetworkSimplex< typename primalsolver_type::graph_type, value_type, value_type > alg_type
algorithm type
Definition: MinCostFlow.h:702
expression_type const & expression() const
Definition: Solvers.h:1028
Cycle canceling algorithm for min-cost flow.
CapacityScaling & operator=(CapacityScaling const &rhs)
assignment
Definition: MinCostFlow.h:524
void copy(CostScaling const &rhs)
copy object
MinCostFlowSolver< T, V > base_type
base type
Definition: MinCostFlow.h:696
virtual SolverProperty operator()(primalsolver_type *d)
API to run min-cost flow solver.
Definition: MinCostFlow.h:634
node_value_map_type const & supplyMap() const
Definition: MinCostFlow.h:194
int m_factor
scaling factor for the algorithm
namespace for Limbo
Definition: GraphUtility.h:22
base_type::primalsolver_type primalsolver_type
dual min-cost flow solver type
Definition: MinCostFlow.h:794
CostScaling(typename alg_type::Method method=alg_type::PARTIAL_AUGMENT, int factor=16)
constructor
Definition: MinCostFlow.h:607
MinCostFlow & operator=(MinCostFlow const &rhs)
assignment, forbidden
std::iterator_traits< Iterator >::value_type max(Iterator first, Iterator last)
get max of an array
Definition: Math.h:61
arc_cost_map_type const & costMap() const
Definition: MinCostFlow.h:189
NetworkSimplex(typename alg_type::PivotRule pivotRule=alg_type::BLOCK_SEARCH)
constructor
Definition: MinCostFlow.h:706
base_type::primalsolver_type primalsolver_type
dual min-cost flow solver type
Definition: MinCostFlow.h:698
coefficient_value_type rightHandSide() const
Definition: Solvers.h:1034
void copy(CycleCanceling const &rhs)
copy object
NetworkSimplex(NetworkSimplex const &rhs)
copy constructor
Definition: MinCostFlow.h:713
the model is unbounded
Definition: Solvers.h:39
alg_type::Method m_method
PUSH, AUGMENT, PARTIAL_AUGMENT.
virtual SolverProperty operator()(primalsolver_type *d)
API to run min-cost flow solver.
Definition: MinCostFlow.h:828
void copy(NetworkSimplex const &rhs)
copy object
#define limboAssert(condition)
custom assertion without message
Definition: AssertMsg.h:64
int limboPrint(MessageType m, const char *format,...)
formatted print with prefix
Definition: PrintMsg.h:49
std::vector< term_type > const & terms() const
Definition: Solvers.h:655
optimally solved
Definition: Solvers.h:36
Cost scaling algorithm for min-cost flow.
MinCostFlowSolver(MinCostFlowSolver const &rhs)
copy constructor
Definition: MinCostFlow.h:467
MinCostFlowSolver & operator=(MinCostFlowSolver const &rhs)
assignment
Definition: MinCostFlow.h:473
alg_type::PivotRule m_pivotRule
pivot rule for the algorithm, FIRST_ELIGIBLE, BEST_ELIGIBLE, BLOCK_SEARCH, CANDIDATE_LIST, ALTERING_LIST
MinCostFlowSolver< T, V > base_type
base type
Definition: MinCostFlow.h:596
void copy(MinCostFlowSolver const &)
copy object
variable_type const & variable() const
Definition: Solvers.h:384
model to describe an optimization problem
Definition: Solvers.h:80
arc_value_map_type m_mLower
lower bound of flow, usually zero
Definition: MinCostFlow.h:163
model_type * m_model
model for the problem
Definition: MinCostFlow.h:160
MinCostFlow< T, V > primalsolver_type
dual min-cost flow solver type
Definition: MinCostFlow.h:461
minimize objective
Definition: Solvers.h:31
#define limboAssertMsg(condition, args...)
custom assertion with message
Definition: AssertMsg.h:52
arc_value_map_type m_mUpper
upper bound of flow, arc capacity in min-cost flow
Definition: MinCostFlow.h:164
CostScaling(CostScaling const &rhs)
copy constructor
Definition: MinCostFlow.h:615
void scale(coefficient_value_type factor)
scale constraint by a scaling factor
Definition: Solvers.h:1076
SolverProperty solve(solver_type *solver)
kernel function to solve the problem
Definition: MinCostFlow.h:252
MinCostFlow(model_type *model)
constructor
Definition: MinCostFlow.h:91
base_type::primalsolver_type primalsolver_type
dual min-cost flow solver type
Definition: MinCostFlow.h:598
node_pot_map_type m_mPotential
solution of min-cost flow, which is the dual solution of LP
Definition: MinCostFlow.h:170
unsigned int id() const
Definition: Solvers.h:1024
A base class of min-cost flow solver.