test/radix_sort_test.cc
author Alpar Juttner <alpar@cs.elte.hu>
Mon, 07 Jul 2014 11:57:45 +0200
branch1.3
changeset 1316 d9e802637310
parent 1211 1bafdbd2fc46
child 1341 c199e9976d93
permissions -rw-r--r--
Merge bugfixes #480, #481, #482 and #487 to branch 1.3
alpar@465
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@464
     2
 *
alpar@465
     3
 * This file is a part of LEMON, a generic C++ optimization library.
deba@464
     4
 *
alpar@1270
     5
 * Copyright (C) 2003-2013
deba@464
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@464
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@464
     8
 *
deba@464
     9
 * Permission to use, modify and distribute this software is granted
deba@464
    10
 * provided that this copyright notice appears in all copies. For
deba@464
    11
 * precise terms see the accompanying LICENSE file.
deba@464
    12
 *
deba@464
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@464
    14
 * express or implied, and with no claim as to its suitability for any
deba@464
    15
 * purpose.
deba@464
    16
 *
deba@464
    17
 */
deba@464
    18
deba@464
    19
#include <lemon/time_measure.h>
deba@464
    20
#include <lemon/smart_graph.h>
deba@464
    21
#include <lemon/maps.h>
deba@464
    22
#include <lemon/radix_sort.h>
deba@464
    23
#include <lemon/math.h>
deba@464
    24
deba@464
    25
#include "test_tools.h"
deba@464
    26
deba@464
    27
#include <vector>
alpar@1211
    28
#include <list>
deba@464
    29
#include <algorithm>
deba@464
    30
deba@464
    31
using namespace lemon;
deba@464
    32
deba@464
    33
static const int n = 10000;
deba@464
    34
deba@464
    35
struct Negate {
deba@464
    36
  typedef int argument_type;
deba@464
    37
  typedef int result_type;
deba@464
    38
  int operator()(int a) { return - a; }
deba@464
    39
};
deba@464
    40
deba@464
    41
int negate(int a) { return - a; }
deba@464
    42
alpar@1211
    43
template<class T>
alpar@1211
    44
bool isTheSame(T &a, T&b)
alpar@1211
    45
{
alpar@1211
    46
  typename T::iterator ai=a.begin();
alpar@1211
    47
  typename T::iterator bi=b.begin();
alpar@1211
    48
  for(;ai!=a.end()||bi!=b.end();++ai,++bi)
alpar@1211
    49
    if(*ai!=*bi) return false;
alpar@1211
    50
  return ai==a.end()&&bi==b.end();
alpar@1211
    51
}
deba@464
    52
alpar@1211
    53
template<class T>
alpar@1211
    54
T listsort(typename T::iterator b, typename T::iterator e)
alpar@1270
    55
{
alpar@1211
    56
  if(b==e) return T();
alpar@1211
    57
  typename T::iterator bn=b;
alpar@1211
    58
  if(++bn==e) {
alpar@1211
    59
    T l;
alpar@1211
    60
    l.push_back(*b);
alpar@1211
    61
    return l;
alpar@1211
    62
  }
alpar@1211
    63
  typename T::iterator m=b;
alpar@1211
    64
  bool x=false;
alpar@1211
    65
  for(typename T::iterator i=b;i!=e;++i,x=!x)
alpar@1211
    66
    if(x) ++m;
alpar@1211
    67
  T l1(listsort<T>(b,m));
alpar@1211
    68
  T l2(listsort<T>(m,e));
alpar@1211
    69
  T l;
alpar@1211
    70
  while((!l1.empty())&&(!l2.empty()))
alpar@1211
    71
    if(l1.front()<=l2.front())
alpar@1211
    72
      {
alpar@1211
    73
        l.push_back(l1.front());
alpar@1211
    74
        l1.pop_front();
alpar@1211
    75
      }
alpar@1211
    76
    else {
alpar@1211
    77
      l.push_back(l2.front());
alpar@1211
    78
      l2.pop_front();
alpar@1211
    79
    }
alpar@1211
    80
  while(!l1.empty())
alpar@1211
    81
    {
alpar@1211
    82
      l.push_back(l1.front());
alpar@1211
    83
      l1.pop_front();
alpar@1211
    84
    }
alpar@1211
    85
  while(!l2.empty())
alpar@1211
    86
    {
alpar@1211
    87
      l.push_back(l2.front());
alpar@1211
    88
      l2.pop_front();
alpar@1211
    89
    }
alpar@1211
    90
  return l;
alpar@1211
    91
}
alpar@1211
    92
alpar@1211
    93
template<class T>
alpar@1211
    94
void generateIntSequence(int n, T & data) {
deba@464
    95
  int prime = 9973;
deba@464
    96
  int root = 136, value = 1;
deba@464
    97
  for (int i = 0; i < n; ++i) {
deba@464
    98
    data.push_back(value - prime / 2);
deba@464
    99
    value = (value * root) % prime;
deba@464
   100
  }
deba@464
   101
}
deba@464
   102
alpar@1211
   103
template<class T>
alpar@1211
   104
void generateCharSequence(int n, T & data) {
deba@464
   105
  int prime = 251;
deba@464
   106
  int root = 3, value = root;
deba@464
   107
  for (int i = 0; i < n; ++i) {
deba@464
   108
    data.push_back(static_cast<unsigned char>(value));
deba@464
   109
    value = (value * root) % prime;
deba@464
   110
  }
deba@464
   111
}
deba@464
   112
deba@464
   113
void checkRadixSort() {
deba@464
   114
  {
deba@464
   115
    std::vector<int> data1;
deba@464
   116
    generateIntSequence(n, data1);
deba@464
   117
deba@464
   118
    std::vector<int> data2(data1);
deba@464
   119
    std::sort(data1.begin(), data1.end());
deba@464
   120
deba@464
   121
    radixSort(data2.begin(), data2.end());
deba@464
   122
    for (int i = 0; i < n; ++i) {
deba@464
   123
      check(data1[i] == data2[i], "Test failed");
deba@464
   124
    }
deba@464
   125
alpar@1211
   126
    // radixSort(data2.begin(), data2.end(), Negate());
alpar@1211
   127
    // for (int i = 0; i < n; ++i) {
alpar@1211
   128
    //   check(data1[i] == data2[n - 1 - i], "Test failed");
alpar@1211
   129
    // }
deba@464
   130
alpar@1211
   131
    // radixSort(data2.begin(), data2.end(), negate);
alpar@1211
   132
    // for (int i = 0; i < n; ++i) {
alpar@1211
   133
    //   check(data1[i] == data2[n - 1 - i], "Test failed");
alpar@1211
   134
    // }
deba@464
   135
alpar@465
   136
  }
alpar@465
   137
deba@464
   138
  {
deba@464
   139
    std::vector<unsigned char> data1(n);
deba@464
   140
    generateCharSequence(n, data1);
deba@464
   141
deba@464
   142
    std::vector<unsigned char> data2(data1);
deba@464
   143
    std::sort(data1.begin(), data1.end());
deba@464
   144
deba@464
   145
    radixSort(data2.begin(), data2.end());
deba@464
   146
    for (int i = 0; i < n; ++i) {
deba@464
   147
      check(data1[i] == data2[i], "Test failed");
deba@464
   148
    }
deba@464
   149
deba@464
   150
  }
alpar@1211
   151
  {
alpar@1211
   152
    std::list<int> data1;
alpar@1211
   153
    generateIntSequence(n, data1);
alpar@1211
   154
alpar@1211
   155
    std::list<int> data2(listsort<std::list<int> >(data1.begin(), data1.end()));
alpar@1211
   156
alpar@1211
   157
    radixSort(data1.begin(), data1.end());
alpar@1211
   158
alpar@1211
   159
    check(isTheSame(data1,data2), "Test failed");
alpar@1211
   160
alpar@1211
   161
alpar@1211
   162
    // radixSort(data2.begin(), data2.end(), Negate());
alpar@1211
   163
    // check(isTheSame(data1,data2), "Test failed");
alpar@1211
   164
    // for (int i = 0; i < n; ++i) {
alpar@1211
   165
    //   check(data1[i] == data2[n - 1 - i], "Test failed");
alpar@1211
   166
    // }
alpar@1211
   167
alpar@1211
   168
    // radixSort(data2.begin(), data2.end(), negate);
alpar@1211
   169
    // for (int i = 0; i < n; ++i) {
alpar@1211
   170
    //   check(data1[i] == data2[n - 1 - i], "Test failed");
alpar@1211
   171
    // }
alpar@1211
   172
alpar@1211
   173
  }
alpar@1211
   174
alpar@1211
   175
  {
alpar@1211
   176
    std::list<unsigned char> data1(n);
alpar@1211
   177
    generateCharSequence(n, data1);
alpar@1211
   178
alpar@1211
   179
    std::list<unsigned char> data2(listsort<std::list<unsigned char> >
alpar@1211
   180
                                   (data1.begin(),
alpar@1211
   181
                                    data1.end()));
alpar@1211
   182
alpar@1211
   183
    radixSort(data1.begin(), data1.end());
alpar@1211
   184
    check(isTheSame(data1,data2), "Test failed");
alpar@1211
   185
alpar@1211
   186
  }
deba@464
   187
}
deba@464
   188
deba@464
   189
deba@466
   190
void checkStableRadixSort() {
deba@464
   191
  {
deba@464
   192
    std::vector<int> data1;
deba@464
   193
    generateIntSequence(n, data1);
deba@464
   194
deba@464
   195
    std::vector<int> data2(data1);
deba@464
   196
    std::sort(data1.begin(), data1.end());
deba@464
   197
deba@466
   198
    stableRadixSort(data2.begin(), data2.end());
deba@464
   199
    for (int i = 0; i < n; ++i) {
deba@464
   200
      check(data1[i] == data2[i], "Test failed");
deba@464
   201
    }
deba@464
   202
deba@466
   203
    stableRadixSort(data2.begin(), data2.end(), Negate());
deba@464
   204
    for (int i = 0; i < n; ++i) {
deba@464
   205
      check(data1[i] == data2[n - 1 - i], "Test failed");
deba@464
   206
    }
deba@464
   207
deba@466
   208
    stableRadixSort(data2.begin(), data2.end(), negate);
deba@464
   209
    for (int i = 0; i < n; ++i) {
deba@464
   210
      check(data1[i] == data2[n - 1 - i], "Test failed");
deba@464
   211
    }
alpar@465
   212
  }
deba@464
   213
deba@464
   214
  {
deba@464
   215
    std::vector<unsigned char> data1(n);
deba@464
   216
    generateCharSequence(n, data1);
deba@464
   217
deba@464
   218
    std::vector<unsigned char> data2(data1);
deba@464
   219
    std::sort(data1.begin(), data1.end());
deba@464
   220
deba@464
   221
    radixSort(data2.begin(), data2.end());
deba@464
   222
    for (int i = 0; i < n; ++i) {
deba@464
   223
      check(data1[i] == data2[i], "Test failed");
deba@464
   224
    }
deba@464
   225
deba@464
   226
  }
alpar@1211
   227
  {
alpar@1211
   228
    std::list<int> data1;
alpar@1211
   229
    generateIntSequence(n, data1);
alpar@1211
   230
alpar@1211
   231
    std::list<int> data2(listsort<std::list<int> >(data1.begin(),
alpar@1211
   232
                                                   data1.end()));
alpar@1211
   233
    stableRadixSort(data1.begin(), data1.end());
alpar@1211
   234
    check(isTheSame(data1,data2), "Test failed");
alpar@1211
   235
alpar@1211
   236
    // stableRadixSort(data2.begin(), data2.end(), Negate());
alpar@1211
   237
    // for (int i = 0; i < n; ++i) {
alpar@1211
   238
    //   check(data1[i] == data2[n - 1 - i], "Test failed");
alpar@1211
   239
    // }
alpar@1211
   240
alpar@1211
   241
    // stableRadixSort(data2.begin(), data2.end(), negate);
alpar@1211
   242
    // for (int i = 0; i < n; ++i) {
alpar@1211
   243
    //   check(data1[i] == data2[n - 1 - i], "Test failed");
alpar@1211
   244
    // }
alpar@1211
   245
  }
alpar@1211
   246
alpar@1211
   247
  {
alpar@1211
   248
    std::list<unsigned char> data1(n);
alpar@1211
   249
    generateCharSequence(n, data1);
alpar@1211
   250
alpar@1211
   251
    std::list<unsigned char> data2(listsort<std::list<unsigned char> >
alpar@1211
   252
                                   (data1.begin(),
alpar@1211
   253
                                    data1.end()));
alpar@1211
   254
    radixSort(data1.begin(), data1.end());
alpar@1211
   255
    check(isTheSame(data1,data2), "Test failed");
alpar@1211
   256
alpar@1211
   257
  }
deba@464
   258
}
deba@464
   259
deba@464
   260
int main() {
deba@464
   261
alpar@465
   262
  checkRadixSort();
deba@466
   263
  checkStableRadixSort();
deba@464
   264
deba@464
   265
  return 0;
deba@464
   266
}