test/min_mean_cycle_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 806 fa6f37d7a25b
parent 766 97744b6dabf8
child 864 d3ea191c3412
permissions -rw-r--r--
Entirely rework CapacityScaling (#180)

- Use the new interface similarly to NetworkSimplex.
- Rework the implementation using an efficient internal structure
for handling the residual network. This improvement made the
code much faster (up to 2-5 times faster on large graphs).
- Handle GEQ supply type (LEQ is not supported).
- Handle negative costs for arcs of finite capacity.
(Note that this algorithm cannot handle arcs of negative cost
and infinite upper bound, thus it returns UNBOUNDED if such
an arc exists.)
- Extend the documentation.
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library.
     4  *
     5  * Copyright (C) 2003-2009
     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 
    28 #include <lemon/karp.h>
    29 #include <lemon/hartmann_orlin.h>
    30 #include <lemon/howard.h>
    31 
    32 #include "test_tools.h"
    33 
    34 using namespace lemon;
    35 
    36 char 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 
    64                         
    65 // Check the interface of an MMC algorithm
    66 template <typename GR, typename Value>
    67 struct 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> >
    76         ::template SetLargeValue<Value>
    77         ::Create MmcAlg;
    78       MmcAlg mmc(me.g, me.length);
    79       const MmcAlg& const_mmc = mmc;
    80       
    81       typename MmcAlg::Tolerance tol = const_mmc.tolerance();
    82       mmc.tolerance(tol);
    83       
    84       b = mmc.cycle(p).run();
    85       b = mmc.findMinMean();
    86       b = mmc.findCycle();
    87 
    88       v = const_mmc.cycleLength();
    89       i = const_mmc.cycleArcNum();
    90       d = const_mmc.cycleMean();
    91       p = const_mmc.cycle();
    92     }
    93 
    94     typedef concepts::ReadMap<typename GR::Arc, Value> LM;
    95   
    96     GR g;
    97     LM length;
    98     ListPath<GR> p;
    99     Value v;
   100     int i;
   101     double d;
   102     bool b;
   103   };
   104 };
   105 
   106 // Perform a test with the given parameters
   107 template <typename MMC>
   108 void checkMmcAlg(const SmartDigraph& gr,
   109                  const SmartDigraph::ArcMap<int>& lm,
   110                  const SmartDigraph::ArcMap<int>& cm,
   111                  int length, int size) {
   112   MMC alg(gr, lm);
   113   alg.findMinMean();
   114   check(alg.cycleMean() == static_cast<double>(length) / size,
   115         "Wrong cycle mean");
   116   alg.findCycle();
   117   check(alg.cycleLength() == length && alg.cycleArcNum() == size,
   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
   129 template <typename T1, typename T2>
   130 struct IsSameType {
   131   static const int result = 0;
   132 };
   133 
   134 template <typename T>
   135 struct IsSameType<T,T> {
   136   static const int result = 1;
   137 };
   138 
   139 
   140 int 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;
   150 
   151     // Karp
   152     checkConcept< MmcClassConcept<GR, int>,
   153                   Karp<GR, concepts::ReadMap<GR::Arc, int> > >();
   154     checkConcept< MmcClassConcept<GR, float>,
   155                   Karp<GR, concepts::ReadMap<GR::Arc, float> > >();
   156     
   157     // HartmannOrlin
   158     checkConcept< MmcClassConcept<GR, int>,
   159                   HartmannOrlin<GR, concepts::ReadMap<GR::Arc, int> > >();
   160     checkConcept< MmcClassConcept<GR, float>,
   161                   HartmannOrlin<GR, concepts::ReadMap<GR::Arc, float> > >();
   162     
   163     // Howard
   164     checkConcept< MmcClassConcept<GR, int>,
   165                   Howard<GR, concepts::ReadMap<GR::Arc, int> > >();
   166     checkConcept< MmcClassConcept<GR, float>,
   167                   Howard<GR, concepts::ReadMap<GR::Arc, float> > >();
   168 
   169     if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, int> >::LargeValue,
   170           long_int>::result == 0) check(false, "Wrong LargeValue type");
   171     if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, float> >::LargeValue,
   172           double>::result == 0) check(false, "Wrong LargeValue type");
   173   }
   174 
   175   // Run various tests
   176   {
   177     typedef SmartDigraph GR;
   178     DIGRAPH_TYPEDEFS(GR);
   179     
   180     GR gr;
   181     IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
   182     IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
   183     
   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 
   196     // Karp
   197     checkMmcAlg<Karp<GR, IntArcMap> >(gr, l1, c1,  6, 3);
   198     checkMmcAlg<Karp<GR, IntArcMap> >(gr, l2, c2,  5, 2);
   199     checkMmcAlg<Karp<GR, IntArcMap> >(gr, l3, c3,  0, 1);
   200     checkMmcAlg<Karp<GR, IntArcMap> >(gr, l4, c4, -1, 1);
   201 
   202     // HartmannOrlin
   203     checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l1, c1,  6, 3);
   204     checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l2, c2,  5, 2);
   205     checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l3, c3,  0, 1);
   206     checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l4, c4, -1, 1);
   207 
   208     // Howard
   209     checkMmcAlg<Howard<GR, IntArcMap> >(gr, l1, c1,  6, 3);
   210     checkMmcAlg<Howard<GR, IntArcMap> >(gr, l2, c2,  5, 2);
   211     checkMmcAlg<Howard<GR, IntArcMap> >(gr, l3, c3,  0, 1);
   212     checkMmcAlg<Howard<GR, IntArcMap> >(gr, l4, c4, -1, 1);
   213   }
   214 
   215   return 0;
   216 }