Limbo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Lgf.h
Go to the documentation of this file.
1 
11 #ifndef _LIMBO_SOLVERS_LPMCF_LGF_H
12 #define _LIMBO_SOLVERS_LPMCF_LGF_H
13 
14 #include <cstdlib>
15 #include <iostream>
16 #include <cassert>
17 #include <string>
18 #include <cctype>
19 #include <ctime>
20 
21 #include <lemon/network_simplex.h>
22 #include <lemon/cost_scaling.h>
23 //#include <lemon/capacity_scaling.h>
24 //#include <lemon/cycle_canceling.h>
25 
26 #include <lemon/list_graph.h>
27 #include <lemon/smart_graph.h>
28 
29 #include <lemon/lgf_reader.h>
30 #include <lemon/lgf_writer.h>
31 #include <lemon/graph_to_eps.h>
32 #include <lemon/math.h>
33 
35 
37 namespace limbo
38 {
40 namespace solvers
41 {
43 namespace lpmcf
44 {
45 
46 using std::cout;
47 using std::endl;
48 using std::string;
49 
53 template <typename T>
54 class Lgf
55 {
56  public:
58  // value_type can only be integer types
59  typedef T value_type;
60  typedef value_type cost_type;
61  typedef lemon::SmartDigraph graph_type;
62  typedef graph_type::Node node_type;
63  typedef graph_type::Arc arc_type;
64  typedef graph_type::NodeMap<value_type> node_value_map_type;
65  typedef graph_type::NodeMap<string> node_name_map_type;
66  typedef graph_type::ArcMap<value_type> arc_value_map_type;
67  typedef graph_type::ArcMap<value_type> arc_cost_map_type;
68  typedef graph_type::ArcMap<value_type> arc_flow_map_type;
69  typedef graph_type::NodeMap<value_type> node_pot_map_type; // potential of each node
70 
71  // four kinds of algrithms for min-cost flow
72  typedef lemon::NetworkSimplex<graph_type, value_type, cost_type> alg_network_simplex_type;
73  typedef lemon::CostScaling<graph_type, value_type, cost_type> alg_cost_scaling_type;
74 // typedef lemon::CapacityScaling<graph_type, value_type, cost_type> alg_capacity_scaling_type;
75 // typedef lemon::CycleCanceling<graph_type, value_type, cost_type> alg_cycle_canceling_type;
76 
77 // typedef alg_network_simplex_type alg_type;
78  typedef alg_cost_scaling_type alg_type;
80 
82  Lgf()
83  : m_graph(),
84  m_hLower(m_graph),
85  m_hUpper(m_graph),
86  m_hCost(m_graph),
89  m_totalcost(std::numeric_limits<cost_type>::max()),
90  m_hFlow(m_graph),
92  {
93  }
95  virtual ~Lgf() {}
96 
99  typename alg_type::ProblemType operator() (string const& filename)
100  {
101  this->read_lgf(filename);
102 
103  typename alg_type::ProblemType status = this->run();
104  if (status == alg_type::OPTIMAL)
105  this->print_solution(filename+".sol");
106 
107  return status;
108  }
109 
112  virtual void print_graph(string const& filename) const
113  {
114  typedef lemon::dim2::Point<int> Point;
115 
116  lemon::Palette palette;
117 
118  graph_type::NodeMap<Point> coords(m_graph);
119  graph_type::NodeMap<double> sizes(m_graph);
120  graph_type::NodeMap<int> colors(m_graph);
121  graph_type::NodeMap<int> shapes(m_graph);
122  graph_type::ArcMap<int> acolors(m_graph);
123  graph_type::ArcMap<int> widths(m_graph);
124  //lemon::IdMap<graph_type, node_type> id(m_graph);
125 
126  srand(1000);
127  int64_t i = 0;
128  for (graph_type::NodeIt v(m_graph); v != lemon::INVALID; ++v, ++i)
129  {
130  coords[v] = Point(
131  10*(i+rand()%(m_graph.maxNodeId()<<2)),
132  10*(i+rand()%(m_graph.maxNodeId()<<2))
133  );
134  sizes[v] = 1;
135  colors[v] = 1;
136  shapes[v] = 0;
137  }
138  i = 0;
139  for (graph_type::ArcIt a(m_graph); a != lemon::INVALID; ++a, ++i)
140  {
141  acolors[a] = 0;
142  widths[a] = 1;
143  }
144 
145  // dump eps figure
146  lemon::graphToEps(m_graph, filename+".eps")
147  .title("LpMcfD EPS figure")
148  .coords(coords)
149  .absoluteNodeSizes().absoluteArcWidths()
150  .nodeScale(2).nodeSizes(sizes)
151  .nodeShapes(shapes)
152  .nodeColors(lemon::composeMap(palette,colors))
153  .arcColors(lemon::composeMap(palette,acolors))
154  .arcWidthScale(.4).arcWidths(widths)
155  .nodeTexts(m_hName).nodeTextSize(3)
156  .enableParallel().parArcDist(1)
157  .drawArrows().arrowWidth(1).arrowLength(1)
158  .run();
159  // dump lgf file
160  lemon::DigraphWriter<graph_type>(m_graph, filename+".lgf")
161  .nodeMap("name", m_hName)
162  .nodeMap("supply", m_hSupply)
163  .arcMap("capacity_lower", m_hLower)
164  .arcMap("capacity_upper", m_hUpper)
165  .arcMap("cost", m_hCost)
166  .run();
167  }
170  virtual void print_solution(string const& filename) const
171  {
172  std::ofstream out (filename.c_str());
173  if (!out.good())
174  {
175  cout << "failed to open " << filename << endl;
176  return;
177  }
178 
179  out << "total cost: " << m_totalcost << endl;
180  out << "############# MCF Flow #############" << endl;
181  for (graph_type::ArcIt a(m_graph); a != lemon::INVALID; ++a)
182  {
183  out << m_graph.id(a) << ": "
184  << m_hName[m_graph.source(a)] << "->" << m_hName[m_graph.target(a)] << ": "
185  << m_hFlow[a] << endl;
186  }
187  out << "############# MCF Potential #############" << endl;
188  for (graph_type::NodeIt v(m_graph); v != lemon::INVALID; ++v)
189  {
190  out << m_hName[v] << ": " << m_hPot[v] << endl;
191  }
192 
193  out.close();
194  }
197  void read_lgf(string const& lgfFile)
198  {
199  lemon::DigraphReader<graph_type>(m_graph, lgfFile)
200  .nodeMap("supply", m_hSupply)
201  .nodeMap("name", m_hName)
202  .arcMap("capacity_lower", m_hLower)
203  .arcMap("capacity_upper", m_hUpper)
204  .arcMap("cost", m_hCost)
205  .run();
206  }
207  protected:
210  typename alg_type::ProblemType run()
211  {
212  // 1. choose algorithm
213  alg_type alg (m_graph);
214 
215  // 2. run
216  typename alg_type::ProblemType status = alg.reset().resetParams()
217  .lowerMap(m_hLower)
218  .upperMap(m_hUpper)
219  .costMap(m_hCost)
220  .supplyMap(m_hSupply)
221 // .stSupply(m_st, m_st, m_st_supply)
222  .run();
223 
224  // 3. check results
225 #ifdef DEBUG
226  switch (status)
227  {
228  case alg_type::OPTIMAL:
229  cout << "OPTIMAL" << endl;
230  break;
232  cout << "INFEASIBLE" << endl;
233  break;
234  case alg_type::UNBOUNDED:
235  cout << "UNBOUNDED" << endl;
236  break;
237  }
238 
239  assert_msg(status == alg_type::OPTIMAL, "failed to achieve OPTIMAL solution");
240 #endif
241  // 4. update solution
242  if (status == alg_type::OPTIMAL)
243  {
244  m_totalcost = alg.template totalCost<cost_type>();
245  // get dual solution of LP, which is the flow of mcf, skip this if not necessary
246  alg.flowMap(m_hFlow);
247  // get solution of LP, which is the dual solution of mcf
248  alg.potentialMap(m_hPot);
249  }
250 
251  return status;
252  }
253 
254  graph_type m_graph;
255  arc_value_map_type m_hLower;
256  arc_value_map_type m_hUpper;
257  arc_cost_map_type m_hCost;
258  node_value_map_type m_hSupply;
259  node_name_map_type m_hName;
260  cost_type m_totalcost;
261 
262  arc_flow_map_type m_hFlow;
263  node_pot_map_type m_hPot;
264 };
265 
266 } // namespace lpmcf
267 } // namespace solvers
268 } // limbo
269 
270 #endif
arc_flow_map_type m_hFlow
solution of min-cost flow, which is the dual solution of LP
Definition: Lgf.h:262
graph_type m_graph
input graph
Definition: Lgf.h:254
virtual void print_solution(string const &filename) const
print solution
Definition: Lgf.h:170
node_name_map_type m_hName
node name in mcf
Definition: Lgf.h:259
node_value_map_type m_hSupply
node supply in mcf
Definition: Lgf.h:258
alg_type::ProblemType operator()(string const &filename)
API to run the algorithm.
Definition: Lgf.h:99
virtual ~Lgf()
destructor
Definition: Lgf.h:95
cost_type m_totalcost
total cost after solving
Definition: Lgf.h:260
alg_type::ProblemType run()
run algorithm
Definition: Lgf.h:210
a custom point class
Definition: test_p2r.cpp:22
arc_cost_map_type m_hCost
arc cost in mcf
Definition: Lgf.h:257
assertion with message
solve network flow graph with min-cost flow
Definition: Lgf.h:54
node_pot_map_type m_hPot
dual solution of min-cost flow, which is the solution of LP
Definition: Lgf.h:263
the model is infeasible
Definition: Solvers.h:37
arc_value_map_type m_hLower
lower bound of flow, usually zero
Definition: Lgf.h:255
void read_lgf(string const &lgfFile)
read input file in .lgf format and initialize graph
Definition: Lgf.h:197
namespace for Limbo
Definition: GraphUtility.h:22
std::iterator_traits< Iterator >::value_type max(Iterator first, Iterator last)
get max of an array
Definition: Math.h:61
Lgf()
constructor
Definition: Lgf.h:82
the model is unbounded
Definition: Solvers.h:39
optimally solved
Definition: Solvers.h:36
virtual void print_graph(string const &filename) const
print graph
Definition: Lgf.h:112
arc_value_map_type m_hUpper
upper bound of flow, arc capacity in mcf
Definition: Lgf.h:256
#define assert_msg(condition, message)
assertion with message
Definition: AssertMsg.h:34