test/max_clique_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 1047 ddd3c0d3d9bf
parent 999 c279b19abc62
child 1270 dceba191c00d
permissions -rw-r--r--
Implement the scaling Price Refinement heuristic in CostScaling (#417)
instead of Early Termination.

These two heuristics are similar, but the newer one is faster
and not only makes it possible to skip some epsilon phases, but
it can improve the performance of the other phases, as well.
     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-2010
     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 <sstream>
    20 #include <lemon/list_graph.h>
    21 #include <lemon/full_graph.h>
    22 #include <lemon/grid_graph.h>
    23 #include <lemon/lgf_reader.h>
    24 #include <lemon/grosso_locatelli_pullan_mc.h>
    25 
    26 #include "test_tools.h"
    27 
    28 using namespace lemon;
    29 
    30 char test_lgf[] =
    31   "@nodes\n"
    32   "label max_clique\n"
    33   "1     0\n"
    34   "2     0\n"
    35   "3     0\n"
    36   "4     1\n"
    37   "5     1\n"
    38   "6     1\n"
    39   "7     1\n"
    40   "@edges\n"
    41   "    label\n"
    42   "1 2     1\n"
    43   "1 3     2\n"
    44   "1 4     3\n"
    45   "1 6     4\n"
    46   "2 3     5\n"
    47   "2 5     6\n"
    48   "2 7     7\n"
    49   "3 4     8\n"
    50   "3 5     9\n"
    51   "4 5    10\n"
    52   "4 6    11\n"
    53   "4 7    12\n"
    54   "5 6    13\n"
    55   "5 7    14\n"
    56   "6 7    15\n";
    57       
    58 
    59 // Check with general graphs
    60 template <typename Param>
    61 void checkMaxCliqueGeneral(Param rule) {
    62   typedef ListGraph GR;
    63   typedef GrossoLocatelliPullanMc<GR> McAlg;
    64   typedef McAlg::CliqueNodeIt CliqueIt;
    65   
    66   // Basic tests
    67   {
    68     GR g;
    69     GR::NodeMap<bool> map(g);
    70     McAlg mc(g);
    71     mc.iterationLimit(50);
    72     check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
    73     check(mc.cliqueSize() == 0, "Wrong clique size");
    74     check(CliqueIt(mc) == INVALID, "Wrong CliqueNodeIt");
    75 
    76     GR::Node u = g.addNode();
    77     check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
    78     check(mc.cliqueSize() == 1, "Wrong clique size");
    79     mc.cliqueMap(map);
    80     check(map[u], "Wrong clique map");
    81     CliqueIt it1(mc);
    82     check(static_cast<GR::Node>(it1) == u && ++it1 == INVALID,
    83           "Wrong CliqueNodeIt");
    84     
    85     GR::Node v = g.addNode();
    86     check(mc.run(rule) == McAlg::ITERATION_LIMIT, "Wrong termination cause");
    87     check(mc.cliqueSize() == 1, "Wrong clique size");
    88     mc.cliqueMap(map);
    89     check((map[u] && !map[v]) || (map[v] && !map[u]), "Wrong clique map");
    90     CliqueIt it2(mc);
    91     check(it2 != INVALID && ++it2 == INVALID, "Wrong CliqueNodeIt");
    92 
    93     g.addEdge(u, v);
    94     check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
    95     check(mc.cliqueSize() == 2, "Wrong clique size");
    96     mc.cliqueMap(map);
    97     check(map[u] && map[v], "Wrong clique map");
    98     CliqueIt it3(mc);
    99     check(it3 != INVALID && ++it3 != INVALID && ++it3 == INVALID,
   100           "Wrong CliqueNodeIt");
   101   }
   102 
   103   // Test graph
   104   {
   105     GR g;
   106     GR::NodeMap<bool> max_clique(g);
   107     GR::NodeMap<bool> map(g);
   108     std::istringstream input(test_lgf);
   109     graphReader(g, input)
   110       .nodeMap("max_clique", max_clique)
   111       .run();
   112     
   113     McAlg mc(g);
   114     mc.iterationLimit(50);
   115     check(mc.run(rule) == McAlg::ITERATION_LIMIT, "Wrong termination cause");
   116     check(mc.cliqueSize() == 4, "Wrong clique size");
   117     mc.cliqueMap(map);
   118     for (GR::NodeIt n(g); n != INVALID; ++n) {
   119       check(map[n] == max_clique[n], "Wrong clique map");
   120     }
   121     int cnt = 0;
   122     for (CliqueIt n(mc); n != INVALID; ++n) {
   123       cnt++;
   124       check(map[n] && max_clique[n], "Wrong CliqueNodeIt");
   125     }
   126     check(cnt == 4, "Wrong CliqueNodeIt");
   127   }
   128 }
   129 
   130 // Check with full graphs
   131 template <typename Param>
   132 void checkMaxCliqueFullGraph(Param rule) {
   133   typedef FullGraph GR;
   134   typedef GrossoLocatelliPullanMc<FullGraph> McAlg;
   135   typedef McAlg::CliqueNodeIt CliqueIt;
   136   
   137   for (int size = 0; size <= 40; size = size * 3 + 1) {
   138     GR g(size);
   139     GR::NodeMap<bool> map(g);
   140     McAlg mc(g);
   141     check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
   142     check(mc.cliqueSize() == size, "Wrong clique size");
   143     mc.cliqueMap(map);
   144     for (GR::NodeIt n(g); n != INVALID; ++n) {
   145       check(map[n], "Wrong clique map");
   146     }
   147     int cnt = 0;
   148     for (CliqueIt n(mc); n != INVALID; ++n) cnt++;
   149     check(cnt == size, "Wrong CliqueNodeIt");
   150   }
   151 }
   152 
   153 // Check with grid graphs
   154 template <typename Param>
   155 void checkMaxCliqueGridGraph(Param rule) {
   156   GridGraph g(5, 7);
   157   GridGraph::NodeMap<char> map(g);
   158   GrossoLocatelliPullanMc<GridGraph> mc(g);
   159   
   160   mc.iterationLimit(100);
   161   check(mc.run(rule) == mc.ITERATION_LIMIT, "Wrong termination cause");
   162   check(mc.cliqueSize() == 2, "Wrong clique size");
   163 
   164   mc.stepLimit(100);
   165   check(mc.run(rule) == mc.STEP_LIMIT, "Wrong termination cause");
   166   check(mc.cliqueSize() == 2, "Wrong clique size");
   167 
   168   mc.sizeLimit(2);
   169   check(mc.run(rule) == mc.SIZE_LIMIT, "Wrong termination cause");
   170   check(mc.cliqueSize() == 2, "Wrong clique size");
   171 }
   172 
   173 
   174 int main() {
   175   checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::RANDOM);
   176   checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::DEGREE_BASED);
   177   checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::PENALTY_BASED);
   178 
   179   checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::RANDOM);
   180   checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::DEGREE_BASED);
   181   checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::PENALTY_BASED);
   182                        
   183   checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::RANDOM);
   184   checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::DEGREE_BASED);
   185   checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::PENALTY_BASED);
   186                        
   187   return 0;
   188 }