Limbo
3.5.4
Toggle main menu visibility
Loading...
Searching...
No Matches
limbo
solvers
lpmcf
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
34
#include <
limbo/preprocessor/AssertMsg.h
>
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
),
87
m_hSupply
(
m_graph
),
88
m_hName
(
m_graph
),
89
m_totalcost
(std::numeric_limits<cost_type>::
max
()),
90
m_hFlow
(
m_graph
),
91
m_hPot
(
m_graph
)
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
AssertMsg.h
assertion with message
limboAssertMsg
#define limboAssertMsg(condition, args...)
custom assertion with message
Definition
AssertMsg.h:24
limbo::solvers::lpmcf::Lgf< value_type >::m_hCost
arc_cost_map_type m_hCost
Definition
Lgf.h:257
limbo::solvers::lpmcf::Lgf::print_graph
virtual void print_graph(string const &filename) const
print graph
Definition
Lgf.h:112
limbo::solvers::lpmcf::Lgf::~Lgf
virtual ~Lgf()
destructor
Definition
Lgf.h:95
limbo::solvers::lpmcf::Lgf::run
alg_type::ProblemType run()
run algorithm
Definition
Lgf.h:210
limbo::solvers::lpmcf::Lgf::Lgf
Lgf()
constructor
Definition
Lgf.h:82
limbo::solvers::lpmcf::Lgf::operator()
alg_type::ProblemType operator()(string const &filename)
API to run the algorithm.
Definition
Lgf.h:99
limbo::solvers::lpmcf::Lgf< value_type >::m_totalcost
cost_type m_totalcost
Definition
Lgf.h:260
limbo::solvers::lpmcf::Lgf< value_type >::m_hSupply
node_value_map_type m_hSupply
Definition
Lgf.h:258
limbo::solvers::lpmcf::Lgf< value_type >::m_graph
graph_type m_graph
Definition
Lgf.h:254
limbo::solvers::lpmcf::Lgf< value_type >::m_hName
node_name_map_type m_hName
Definition
Lgf.h:259
limbo::solvers::lpmcf::Lgf< value_type >::m_hPot
node_pot_map_type m_hPot
Definition
Lgf.h:263
limbo::solvers::lpmcf::Lgf::read_lgf
void read_lgf(string const &lgfFile)
read input file in .lgf format and initialize graph
Definition
Lgf.h:197
limbo::solvers::lpmcf::Lgf< value_type >::m_hLower
arc_value_map_type m_hLower
Definition
Lgf.h:255
limbo::solvers::lpmcf::Lgf::print_solution
virtual void print_solution(string const &filename) const
print solution
Definition
Lgf.h:170
limbo::solvers::lpmcf::Lgf< value_type >::m_hFlow
arc_flow_map_type m_hFlow
Definition
Lgf.h:262
limbo::solvers::lpmcf::Lgf< value_type >::m_hUpper
arc_value_map_type m_hUpper
Definition
Lgf.h:256
limbo::solvers::lpmcf
namespace for Limbo.Solvers.lpmcf
Definition
Lgf.h:44
limbo::solvers
namespace for Limbo.Solvers
Definition
DualMinCostFlow.h:25
limbo
namespace for Limbo
Definition
GraphUtility.h:23
limbo::max
std::iterator_traits< Iterator >::value_type max(Iterator first, Iterator last)
get max of an array
Definition
Math.h:61
Point
a custom point class
Definition
test_p2r.cpp:23
Generated on
for Limbo by
1.17.0