gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Exploit the changes of #190 in MCF test file (#234, #190)
0 1 0
default
1 file changed with 1 insertions and 6 deletions:
↑ Collapse diff ↑
Show white space 192 line context
... ...
@@ -140,198 +140,193 @@
140 140
    bool b;
141 141

	
142 142
    typename MCF::FlowMap &flow;
143 143
    typename MCF::PotentialMap &pot;
144 144
  };
145 145

	
146 146
};
147 147

	
148 148

	
149 149
// Check the feasibility of the given flow (primal soluiton)
150 150
template < typename GR, typename LM, typename UM,
151 151
           typename SM, typename FM >
152 152
bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
153 153
                const SM& supply, const FM& flow,
154 154
                ProblemType type = EQ )
155 155
{
156 156
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
157 157

	
158 158
  for (ArcIt e(gr); e != INVALID; ++e) {
159 159
    if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
160 160
  }
161 161

	
162 162
  for (NodeIt n(gr); n != INVALID; ++n) {
163 163
    typename SM::Value sum = 0;
164 164
    for (OutArcIt e(gr, n); e != INVALID; ++e)
165 165
      sum += flow[e];
166 166
    for (InArcIt e(gr, n); e != INVALID; ++e)
167 167
      sum -= flow[e];
168 168
    bool b = (type ==  EQ && sum == supply[n]) ||
169 169
             (type == GEQ && sum >= supply[n]) ||
170 170
             (type == LEQ && sum <= supply[n]);
171 171
    if (!b) return false;
172 172
  }
173 173

	
174 174
  return true;
175 175
}
176 176

	
177 177
// Check the feasibility of the given potentials (dual soluiton)
178 178
// using the "Complementary Slackness" optimality condition
179 179
template < typename GR, typename LM, typename UM,
180 180
           typename CM, typename SM, typename FM, typename PM >
181 181
bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
182 182
                     const CM& cost, const SM& supply, const FM& flow, 
183 183
                     const PM& pi )
184 184
{
185 185
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
186 186

	
187 187
  bool opt = true;
188 188
  for (ArcIt e(gr); opt && e != INVALID; ++e) {
189 189
    typename CM::Value red_cost =
190 190
      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
191 191
    opt = red_cost == 0 ||
192 192
          (red_cost > 0 && flow[e] == lower[e]) ||
193 193
          (red_cost < 0 && flow[e] == upper[e]);
194 194
  }
195 195
  
196 196
  for (NodeIt n(gr); opt && n != INVALID; ++n) {
197 197
    typename SM::Value sum = 0;
198 198
    for (OutArcIt e(gr, n); e != INVALID; ++e)
199 199
      sum += flow[e];
200 200
    for (InArcIt e(gr, n); e != INVALID; ++e)
201 201
      sum -= flow[e];
202 202
    opt = (sum == supply[n]) || (pi[n] == 0);
203 203
  }
204 204
  
205 205
  return opt;
206 206
}
207 207

	
208 208
// Run a minimum cost flow algorithm and check the results
209 209
template < typename MCF, typename GR,
210 210
           typename LM, typename UM,
211 211
           typename CM, typename SM >
212 212
void checkMcf( const MCF& mcf, bool mcf_result,
213 213
               const GR& gr, const LM& lower, const UM& upper,
214 214
               const CM& cost, const SM& supply,
215 215
               bool result, typename CM::Value total,
216 216
               const std::string &test_id = "",
217 217
               ProblemType type = EQ )
218 218
{
219 219
  check(mcf_result == result, "Wrong result " + test_id);
220 220
  if (result) {
221 221
    check(checkFlow(gr, lower, upper, supply, mcf.flowMap(), type),
222 222
          "The flow is not feasible " + test_id);
223 223
    check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
224 224
    check(checkPotential(gr, lower, upper, cost, supply, mcf.flowMap(),
225 225
                         mcf.potentialMap()),
226 226
          "Wrong potentials " + test_id);
227 227
  }
228 228
}
229 229

	
230 230
int main()
231 231
{
232 232
  // Check the interfaces
233 233
  {
234 234
    typedef int Flow;
235 235
    typedef int Cost;
236
    // TODO: This typedef should be enabled if the standard maps are
237
    // reference maps in the graph concepts (See #190).
238
/**/
239
    //typedef concepts::Digraph GR;
240
    typedef ListDigraph GR;
241
/**/
236
    typedef concepts::Digraph GR;
242 237
    checkConcept< McfClassConcept<GR, Flow, Cost>,
243 238
                  NetworkSimplex<GR, Flow, Cost> >();
244 239
  }
245 240

	
246 241
  // Run various MCF tests
247 242
  typedef ListDigraph Digraph;
248 243
  DIGRAPH_TYPEDEFS(ListDigraph);
249 244

	
250 245
  // Read the test digraph
251 246
  Digraph gr;
252 247
  Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), u(gr);
253 248
  Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr);
254 249
  ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
255 250
  Node v, w;
256 251

	
257 252
  std::istringstream input(test_lgf);
258 253
  DigraphReader<Digraph>(gr, input)
259 254
    .arcMap("cost", c)
260 255
    .arcMap("cap", u)
261 256
    .arcMap("low1", l1)
262 257
    .arcMap("low2", l2)
263 258
    .nodeMap("sup1", s1)
264 259
    .nodeMap("sup2", s2)
265 260
    .nodeMap("sup3", s3)
266 261
    .nodeMap("sup4", s4)
267 262
    .nodeMap("sup5", s5)
268 263
    .node("source", v)
269 264
    .node("target", w)
270 265
    .run();
271 266

	
272 267
  // A. Test NetworkSimplex with the default pivot rule
273 268
  {
274 269
    NetworkSimplex<Digraph> mcf(gr);
275 270

	
276 271
    // Check the equality form
277 272
    mcf.upperMap(u).costMap(c);
278 273
    checkMcf(mcf, mcf.supplyMap(s1).run(),
279 274
             gr, l1, u, c, s1, true,  5240, "#A1");
280 275
    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
281 276
             gr, l1, u, c, s2, true,  7620, "#A2");
282 277
    mcf.lowerMap(l2);
283 278
    checkMcf(mcf, mcf.supplyMap(s1).run(),
284 279
             gr, l2, u, c, s1, true,  5970, "#A3");
285 280
    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
286 281
             gr, l2, u, c, s2, true,  8010, "#A4");
287 282
    mcf.reset();
288 283
    checkMcf(mcf, mcf.supplyMap(s1).run(),
289 284
             gr, l1, cu, cc, s1, true,  74, "#A5");
290 285
    checkMcf(mcf, mcf.lowerMap(l2).stSupply(v, w, 27).run(),
291 286
             gr, l2, cu, cc, s2, true,  94, "#A6");
292 287
    mcf.reset();
293 288
    checkMcf(mcf, mcf.run(),
294 289
             gr, l1, cu, cc, s3, true,   0, "#A7");
295 290
    checkMcf(mcf, mcf.boundMaps(l2, u).run(),
296 291
             gr, l2, u, cc, s3, false,   0, "#A8");
297 292

	
298 293
    // Check the GEQ form
299 294
    mcf.reset().upperMap(u).costMap(c).supplyMap(s4);
300 295
    checkMcf(mcf, mcf.run(),
301 296
             gr, l1, u, c, s4, true,  3530, "#A9", GEQ);
302 297
    mcf.problemType(mcf.GEQ);
303 298
    checkMcf(mcf, mcf.lowerMap(l2).run(),
304 299
             gr, l2, u, c, s4, true,  4540, "#A10", GEQ);
305 300
    mcf.problemType(mcf.CARRY_SUPPLIES).supplyMap(s5);
306 301
    checkMcf(mcf, mcf.run(),
307 302
             gr, l2, u, c, s5, false,    0, "#A11", GEQ);
308 303

	
309 304
    // Check the LEQ form
310 305
    mcf.reset().problemType(mcf.LEQ);
311 306
    mcf.upperMap(u).costMap(c).supplyMap(s5);
312 307
    checkMcf(mcf, mcf.run(),
313 308
             gr, l1, u, c, s5, true,  5080, "#A12", LEQ);
314 309
    checkMcf(mcf, mcf.lowerMap(l2).run(),
315 310
             gr, l2, u, c, s5, true,  5930, "#A13", LEQ);
316 311
    mcf.problemType(mcf.SATISFY_DEMANDS).supplyMap(s4);
317 312
    checkMcf(mcf, mcf.run(),
318 313
             gr, l2, u, c, s4, false,    0, "#A14", LEQ);
319 314
  }
320 315

	
321 316
  // B. Test NetworkSimplex with each pivot rule
322 317
  {
323 318
    NetworkSimplex<Digraph> mcf(gr);
324 319
    mcf.supplyMap(s1).costMap(c).capacityMap(u).lowerMap(l2);
325 320

	
326 321
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::FIRST_ELIGIBLE),
327 322
             gr, l2, u, c, s1, true,  5970, "#B1");
328 323
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BEST_ELIGIBLE),
329 324
             gr, l2, u, c, s1, true,  5970, "#B2");
330 325
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BLOCK_SEARCH),
331 326
             gr, l2, u, c, s1, true,  5970, "#B3");
332 327
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::CANDIDATE_LIST),
333 328
             gr, l2, u, c, s1, true,  5970, "#B4");
334 329
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::ALTERING_LIST),
335 330
             gr, l2, u, c, s1, true,  5970, "#B5");
336 331
  }
337 332

	
0 comments (0 inline)