Limbo 3.5.4
Loading...
Searching...
No Matches
Lgf.h
Go to the documentation of this file.
1
10
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
37namespace limbo
38{
40namespace solvers
41{
43namespace lpmcf
44{
45
46using std::cout;
47using std::endl;
48using std::string;
49
53template <typename T>
54class 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(),
89 m_totalcost(std::numeric_limits<cost_type>::max()),
92 {
93 }
94
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 }
168
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 }
195
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;
231 case alg_type::INFEASIBLE:
232 cout << "INFEASIBLE" << endl;
233 break;
234 case alg_type::UNBOUNDED:
235 cout << "UNBOUNDED" << endl;
236 break;
237 }
238
239 limboAssertMsg(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
assertion with message
#define limboAssertMsg(condition, args...)
custom assertion with message
Definition AssertMsg.h:24
virtual void print_graph(string const &filename) const
print graph
Definition Lgf.h:112
virtual ~Lgf()
destructor
Definition Lgf.h:95
alg_type::ProblemType run()
run algorithm
Definition Lgf.h:210
Lgf()
constructor
Definition Lgf.h:82
alg_type::ProblemType operator()(string const &filename)
API to run the algorithm.
Definition Lgf.h:99
node_value_map_type m_hSupply
Definition Lgf.h:258
void read_lgf(string const &lgfFile)
read input file in .lgf format and initialize graph
Definition Lgf.h:197
virtual void print_solution(string const &filename) const
print solution
Definition Lgf.h:170
namespace for Limbo.Solvers.lpmcf
Definition Lgf.h:44
namespace for Limbo.Solvers
namespace for Limbo
std::iterator_traits< Iterator >::value_type max(Iterator first, Iterator last)
get max of an array
Definition Math.h:61
a custom point class
Definition test_p2r.cpp:23