benchmark/min_cut.cc
author kpeter
Sun, 13 Jan 2008 10:26:55 +0000
changeset 2555 a84e52e99f57
parent 2391 14a343be7a5a
permissions -rw-r--r--
Reimplemented MinMeanCycle to be much more efficient.
The new version implements Howard's algorithm instead of Karp's algorithm and
it is at least 10-20 times faster on all the 40-50 random graphs we have tested.
alpar@2391
     1
/* -*- C++ -*-
alpar@2391
     2
 *
alpar@2391
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@2391
     4
 *
alpar@2553
     5
 * Copyright (C) 2003-2008
alpar@2391
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@2391
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@2391
     8
 *
alpar@2391
     9
 * Permission to use, modify and distribute this software is granted
alpar@2391
    10
 * provided that this copyright notice appears in all copies. For
alpar@2391
    11
 * precise terms see the accompanying LICENSE file.
alpar@2391
    12
 *
alpar@2391
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@2391
    14
 * express or implied, and with no claim as to its suitability for any
alpar@2391
    15
 * purpose.
alpar@2391
    16
 *
alpar@2391
    17
 */
alpar@2391
    18
deba@2341
    19
#include <lemon/list_graph.h>
deba@2341
    20
deba@2341
    21
#include <lemon/hao_orlin.h>
deba@2341
    22
#include <lemon/nagamochi_ibaraki.h>
deba@2341
    23
#include <lemon/time_measure.h>
deba@2341
    24
deba@2341
    25
using namespace lemon;
deba@2341
    26
deba@2341
    27
#include "min_cut_graphs.h"
deba@2341
    28
deba@2341
    29
deba@2341
    30
void testRegUGraph();
deba@2341
    31
void testNoiUGraph();
deba@2341
    32
void testBikeWheelUGraph();
deba@2341
    33
deba@2341
    34
int main() {
deba@2341
    35
  testRegUGraph();
deba@2341
    36
  testNoiUGraph();
deba@2341
    37
  testBikeWheelUGraph();
deba@2341
    38
  return 0;
deba@2341
    39
}
deba@2341
    40
deba@2341
    41
//#define int long long
deba@2341
    42
deba@2341
    43
deba@2341
    44
int cutValue(const ListUGraph& g, const ListUGraph::UEdgeMap<int>& c,
deba@2341
    45
           const ListUGraph::NodeMap<bool>& n) {
deba@2341
    46
  int v = 0;
deba@2341
    47
  for (ListUGraph::UEdgeIt e(g); e != INVALID; ++e) {
deba@2341
    48
    if (n[g.source(e)] != n[g.target(e)]) {
deba@2341
    49
      v += c[e];
deba@2341
    50
    }
deba@2341
    51
  }
deba@2341
    52
  return v;
deba@2341
    53
}
deba@2341
    54
deba@2341
    55
int cutSize(const ListUGraph& g, const ListUGraph::NodeMap<bool>& nm) {
deba@2341
    56
  int m = 0;
deba@2341
    57
  for (ListUGraph::NodeIt n(g); n != INVALID; ++n) {
deba@2341
    58
    if (nm[n]) {
deba@2341
    59
      ++m;
deba@2341
    60
    }
deba@2341
    61
  }
deba@2341
    62
  return m;
deba@2341
    63
}
deba@2341
    64
deba@2341
    65
int testNI(const ListUGraph& g, const ListUGraph::UEdgeMap<int>& c) {
deba@2341
    66
  TimeReport tr("Nagamochi-Ibaraki : ");
deba@2341
    67
  NagamochiIbaraki<ListUGraph, ListUGraph::UEdgeMap<int> > alg(g, c);
deba@2341
    68
  alg.run();
deba@2341
    69
  ListUGraph::NodeMap<bool> n(g);
deba@2341
    70
  alg.minCut(n);
deba@2341
    71
  std::cout << "Check : " << cutValue(g, c, n) << ' '
deba@2341
    72
            << cutSize(g, n) << std::endl;
deba@2341
    73
  return alg.minCut();
deba@2341
    74
}
deba@2341
    75
deba@2341
    76
int testHO(const ListUGraph& g, const ListUGraph::UEdgeMap<int>& c) {
deba@2341
    77
  TimeReport tr("Hao-Orlin : ");
deba@2341
    78
  HaoOrlin<ListUGraph, ListUGraph::UEdgeMap<int> > alg(g, c);
deba@2341
    79
  alg.init();
deba@2341
    80
  alg.calculateOut();
deba@2341
    81
  ListUGraph::NodeMap<bool> n(g);
deba@2341
    82
  alg.minCut(n);
deba@2341
    83
  std::cout << "Check : " << cutValue(g, c, n) << ' '
deba@2341
    84
            << cutSize(g, n) << std::endl;
deba@2341
    85
  return alg.minCut();
deba@2341
    86
}
deba@2341
    87
deba@2341
    88
void testBikeWheelUGraph(int n) {
deba@2341
    89
  ListUGraph g;
deba@2341
    90
  ListUGraph::UEdgeMap<int> c(g);
deba@2341
    91
  genBikeWheelUGraph(g, c, n);
deba@2341
    92
  std::cout << "Node number : " << n << std::endl;
deba@2341
    93
  std::cout << "Hao-Orlin : " << testHO(g, c) << std::endl;
deba@2341
    94
  std::cout << "Nagamochi-Ibaraki : " << testNI(g, c) << std::endl;
deba@2341
    95
}
deba@2341
    96
deba@2341
    97
void testBikeWheelUGraph() {
deba@2341
    98
  std::cout << "BikeWheelUGraph : " << std::endl;
deba@2341
    99
  for (int k = 10; k <= 13; ++k) {
deba@2341
   100
    int n = 1 << k;
deba@2341
   101
    testBikeWheelUGraph(n);
deba@2341
   102
  }
deba@2341
   103
}
deba@2341
   104
deba@2341
   105
void testNoiUGraph(int n, int d, int k, int p) {
deba@2341
   106
  ListUGraph g;
deba@2341
   107
  ListUGraph::UEdgeMap<int> c(g);
deba@2341
   108
  genNoiUGraph(g, c, n, d, k, p);
deba@2341
   109
  std::cout << "Node number : " << n << std::endl;
deba@2341
   110
  std::cout << "Density : " << d << std::endl;
deba@2341
   111
  std::cout << "Tight components : " << k << std::endl;
deba@2341
   112
  std::cout << "Scale : " << p << std::endl;
deba@2341
   113
  std::cout << "Hao-Orlin : " << testHO(g, c) << std::endl;
deba@2341
   114
  std::cout << "Nagamochi-Ibaraki : " << testNI(g, c) << std::endl;
deba@2341
   115
}
deba@2341
   116
deba@2341
   117
deba@2341
   118
void testNoiUGraph() {
deba@2341
   119
  std::cout << "NoiUGraph : " << std::endl; 
deba@2341
   120
  std::cout << "Serial 1 : " << std::endl;
deba@2341
   121
  for (int n = 300; n <= 1000; n += 100) {
deba@2341
   122
    testNoiUGraph(n, 50, 1, n);
deba@2341
   123
  }
deba@2341
   124
  std::cout << "Serial 2 : " << std::endl;
deba@2341
   125
  for (int n = 300; n <= 1000; n += 100) {
deba@2341
   126
    testNoiUGraph(n, 50, 2, n);
deba@2341
   127
  }
deba@2341
   128
  std::cout << "Serial 3 : " << std::endl;
deba@2341
   129
  int da3[] = { 5, 10, 25, 50, 75, 100 };
deba@2341
   130
  int dn3 = sizeof(da3) / sizeof(da3[0]);
deba@2341
   131
  for (int d = 0; d < dn3; ++d) {
deba@2341
   132
    testNoiUGraph(1000, da3[d], 1, 1000);
deba@2341
   133
  }
deba@2341
   134
  std::cout << "Serial 4 : " << std::endl;
deba@2341
   135
  for (int d = 0; d < dn3; ++d) {
deba@2341
   136
    testNoiUGraph(1000, da3[d], 2, 1000);
deba@2341
   137
  }
deba@2341
   138
  std::cout << "Serial 5 : " << std::endl;
deba@2341
   139
  int ka5[] = {1, 2, 3, 5, 7, 10, 20, 30, 33, 35, 
deba@2341
   140
               40, 50, 100, 200, 300, 400, 500};
deba@2341
   141
  int kn5 = sizeof(ka5) / sizeof(ka5[0]);
deba@2341
   142
  for (int k = 0; k < kn5; ++k) {
deba@2341
   143
    testNoiUGraph(1000, 50, ka5[k], 1000);
deba@2341
   144
  }
deba@2341
   145
  std::cout << "Serial 6 : " << std::endl;
deba@2341
   146
  int pa6[] = { 5000, 2000, 1000, 500, 250, 100, 50, 10, 1};
deba@2341
   147
  int pn6 = sizeof(pa6) / sizeof(pa6[0]);
deba@2341
   148
  for (int p = 0; p < pn6; ++p) {
deba@2341
   149
    testNoiUGraph(1000, 50, 2, pa6[p]);
deba@2341
   150
  }  
deba@2341
   151
  
deba@2341
   152
}
deba@2341
   153
deba@2341
   154
void testRegUGraph(int n, int d) {
deba@2341
   155
  ListUGraph g;
deba@2341
   156
  ListUGraph::UEdgeMap<int> c(g);
deba@2341
   157
  genRegUGraph(g, c, n, d);
deba@2341
   158
  std::cout << "Node number : " << n << std::endl;
deba@2341
   159
  std::cout << "Number of cycles : " << d << std::endl;
deba@2341
   160
  std::cout << "Hao-Orlin : " << testHO(g, c) << std::endl;
deba@2341
   161
  std::cout << "Nagamochi-Ibaraki : " << testNI(g, c) << std::endl;
deba@2341
   162
}
deba@2341
   163
deba@2341
   164
void testRegUGraph() {
deba@2341
   165
  std::cout << "RegUGraph : " << std::endl; 
deba@2341
   166
  std::cout << "Serial 1 : " << std::endl;
deba@2341
   167
  int da1[] = { 1, 3, 10, 33, 100, 333, 1000};
deba@2341
   168
  int dn1 = sizeof(da1) / sizeof(da1[0]);
deba@2341
   169
  for (int d = 0; d < dn1; ++d) {
deba@2341
   170
    testRegUGraph(1001, da1[d]);
deba@2341
   171
  }
deba@2341
   172
  std::cout << "Serial 2 : " << std::endl;
deba@2341
   173
  int na2[] = { 50, 100, 200, 400, 800};
deba@2341
   174
  int nn2 = sizeof(na2) / sizeof(na2[0]);
deba@2341
   175
  for (int n = 0; n < nn2; ++n) {
deba@2341
   176
    testRegUGraph(na2[n], 50);
deba@2341
   177
  }
deba@2341
   178
  std::cout << "Serial 3 : " << std::endl;
deba@2341
   179
  for (int n = 8; n <= 14; ++n) {
deba@2341
   180
    testRegUGraph(1 << n, 2);
deba@2341
   181
  }
deba@2341
   182
  std::cout << "Serial 4 : " << std::endl;
deba@2341
   183
  for (int n = 7; n <= 11; ++n) {
deba@2341
   184
    testRegUGraph(1 << n, 1 << (n - 4));
deba@2341
   185
  }  
deba@2341
   186
}
deba@2341
   187