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 ↑
Ignore white space 128 line context
... ...
@@ -172,134 +172,129 @@
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);
0 comments (0 inline)