COIN-OR::LEMON - Graph Library

source: lemon-main/test/min_mean_cycle_test.cc @ 1018:2e959a5a0c2d

Last change on this file since 1018:2e959a5a0c2d was 1012:21a9f829ab68, checked in by Peter Kovacs <kpeter@…>, 12 years ago

Optional iteration limit in HowardMmc? (#438)

File size: 6.3 KB
RevLine 
[763]1/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 *
3 * This file is a part of LEMON, a generic C++ optimization library.
4 *
[877]5 * Copyright (C) 2003-2010
[763]6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 *
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
12 *
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
15 * purpose.
16 *
17 */
18
19#include <iostream>
20#include <sstream>
21
22#include <lemon/smart_graph.h>
23#include <lemon/lgf_reader.h>
24#include <lemon/path.h>
25#include <lemon/concepts/digraph.h>
26#include <lemon/concept_check.h>
27
[864]28#include <lemon/karp_mmc.h>
29#include <lemon/hartmann_orlin_mmc.h>
30#include <lemon/howard_mmc.h>
[765]31
[763]32#include "test_tools.h"
33
34using namespace lemon;
35
36char test_lgf[] =
37  "@nodes\n"
38  "label\n"
39  "1\n"
40  "2\n"
41  "3\n"
42  "4\n"
43  "5\n"
44  "6\n"
45  "7\n"
46  "@arcs\n"
47  "    len1 len2 len3 len4  c1 c2 c3 c4\n"
48  "1 2    1    1    1    1   0  0  0  0\n"
49  "2 4    5    5    5    5   1  0  0  0\n"
50  "2 3    8    8    8    8   0  0  0  0\n"
51  "3 2   -2    0    0    0   1  0  0  0\n"
52  "3 4    4    4    4    4   0  0  0  0\n"
53  "3 7   -4   -4   -4   -4   0  0  0  0\n"
54  "4 1    2    2    2    2   0  0  0  0\n"
55  "4 3    3    3    3    3   1  0  0  0\n"
56  "4 4    3    3    0    0   0  0  1  0\n"
57  "5 2    4    4    4    4   0  0  0  0\n"
58  "5 6    3    3    3    3   0  1  0  0\n"
59  "6 5    2    2    2    2   0  1  0  0\n"
60  "6 4   -1   -1   -1   -1   0  0  0  0\n"
61  "6 7    1    1    1    1   0  0  0  0\n"
62  "7 7    4    4    4   -1   0  0  0  1\n";
63
[877]64
[763]65// Check the interface of an MMC algorithm
[864]66template <typename GR, typename Cost>
[763]67struct MmcClassConcept
68{
69  template <typename MMC>
70  struct Constraints {
71    void constraints() {
72      const Constraints& me = *this;
73
74      typedef typename MMC
75        ::template SetPath<ListPath<GR> >
[864]76        ::template SetLargeCost<Cost>
[763]77        ::Create MmcAlg;
[864]78      MmcAlg mmc(me.g, me.cost);
[763]79      const MmcAlg& const_mmc = mmc;
[877]80
[769]81      typename MmcAlg::Tolerance tol = const_mmc.tolerance();
82      mmc.tolerance(tol);
[877]83
[763]84      b = mmc.cycle(p).run();
[864]85      b = mmc.findCycleMean();
[763]86      b = mmc.findCycle();
87
[864]88      v = const_mmc.cycleCost();
89      i = const_mmc.cycleSize();
[763]90      d = const_mmc.cycleMean();
91      p = const_mmc.cycle();
92    }
93
[864]94    typedef concepts::ReadMap<typename GR::Arc, Cost> CM;
[877]95
[763]96    GR g;
[864]97    CM cost;
[763]98    ListPath<GR> p;
[864]99    Cost v;
[763]100    int i;
101    double d;
102    bool b;
103  };
104};
105
106// Perform a test with the given parameters
107template <typename MMC>
108void checkMmcAlg(const SmartDigraph& gr,
109                 const SmartDigraph::ArcMap<int>& lm,
110                 const SmartDigraph::ArcMap<int>& cm,
[864]111                 int cost, int size) {
[763]112  MMC alg(gr, lm);
[1012]113  check(alg.findCycleMean(), "Wrong result");
[864]114  check(alg.cycleMean() == static_cast<double>(cost) / size,
[763]115        "Wrong cycle mean");
116  alg.findCycle();
[864]117  check(alg.cycleCost() == cost && alg.cycleSize() == size,
[763]118        "Wrong path");
119  SmartDigraph::ArcMap<int> cycle(gr, 0);
120  for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
121    ++cycle[a];
122  }
123  for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
124    check(cm[a] == cycle[a], "Wrong path");
125  }
126}
127
128// Class for comparing types
129template <typename T1, typename T2>
130struct IsSameType {
131  static const int result = 0;
132};
133
134template <typename T>
135struct IsSameType<T,T> {
136  static const int result = 1;
137};
138
139
140int main() {
141  #ifdef LEMON_HAVE_LONG_LONG
142    typedef long long long_int;
143  #else
144    typedef long long_int;
145  #endif
146
147  // Check the interface
148  {
149    typedef concepts::Digraph GR;
[765]150
[864]151    // KarpMmc
[765]152    checkConcept< MmcClassConcept<GR, int>,
[864]153                  KarpMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
[765]154    checkConcept< MmcClassConcept<GR, float>,
[864]155                  KarpMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
[877]156
[864]157    // HartmannOrlinMmc
[766]158    checkConcept< MmcClassConcept<GR, int>,
[864]159                  HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
[766]160    checkConcept< MmcClassConcept<GR, float>,
[864]161                  HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
[877]162
[864]163    // HowardMmc
[765]164    checkConcept< MmcClassConcept<GR, int>,
[864]165                  HowardMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
[765]166    checkConcept< MmcClassConcept<GR, float>,
[864]167                  HowardMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
[765]168
[864]169    check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, int> >
170           ::LargeCost, long_int>::result == 1), "Wrong LargeCost type");
171    check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, float> >
172           ::LargeCost, double>::result == 1), "Wrong LargeCost type");
[763]173  }
174
175  // Run various tests
176  {
177    typedef SmartDigraph GR;
178    DIGRAPH_TYPEDEFS(GR);
[877]179
[763]180    GR gr;
181    IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
182    IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
[877]183
[763]184    std::istringstream input(test_lgf);
185    digraphReader(gr, input).
186      arcMap("len1", l1).
187      arcMap("len2", l2).
188      arcMap("len3", l3).
189      arcMap("len4", l4).
190      arcMap("c1", c1).
191      arcMap("c2", c2).
192      arcMap("c3", c3).
193      arcMap("c4", c4).
194      run();
195
[765]196    // Karp
[864]197    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
198    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
199    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
200    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
[765]201
[766]202    // HartmannOrlin
[864]203    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
204    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
205    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
206    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
[766]207
[765]208    // Howard
[864]209    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
210    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
211    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
212    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
[1012]213   
214    // Howard with iteration limit
215    HowardMmc<GR, IntArcMap> mmc(gr, l1);
216    check((mmc.findCycleMean(2) == HowardMmc<GR, IntArcMap>::ITERATION_LIMIT),
217      "Wrong termination cause");
218    check((mmc.findCycleMean(4) == HowardMmc<GR, IntArcMap>::OPTIMAL),
219      "Wrong termination cause");
[763]220  }
221
222  return 0;
223}
Note: See TracBrowser for help on using the repository browser.