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