alpar@442: /* -*- mode: C++; indent-tabs-mode: nil; -*- deba@441: * alpar@442: * This file is a part of LEMON, a generic C++ optimization library. deba@441: * alpar@1092: * Copyright (C) 2003-2013 deba@441: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport deba@441: * (Egervary Research Group on Combinatorial Optimization, EGRES). deba@441: * deba@441: * Permission to use, modify and distribute this software is granted deba@441: * provided that this copyright notice appears in all copies. For deba@441: * precise terms see the accompanying LICENSE file. deba@441: * deba@441: * This software is provided "AS IS" with no warranty of any kind, deba@441: * express or implied, and with no claim as to its suitability for any deba@441: * purpose. deba@441: * deba@441: */ deba@441: deba@441: #include deba@441: #include deba@441: #include deba@441: #include deba@441: #include deba@441: deba@441: #include "test_tools.h" deba@441: deba@441: #include alpar@1043: #include deba@441: #include deba@441: deba@441: using namespace lemon; deba@441: deba@441: static const int n = 10000; deba@441: deba@441: struct Negate { deba@441: typedef int argument_type; deba@441: typedef int result_type; deba@441: int operator()(int a) { return - a; } deba@441: }; deba@441: deba@441: int negate(int a) { return - a; } deba@441: alpar@1043: template alpar@1043: bool isTheSame(T &a, T&b) alpar@1043: { alpar@1043: typename T::iterator ai=a.begin(); alpar@1043: typename T::iterator bi=b.begin(); alpar@1043: for(;ai!=a.end()||bi!=b.end();++ai,++bi) alpar@1043: if(*ai!=*bi) return false; alpar@1043: return ai==a.end()&&bi==b.end(); alpar@1043: } deba@441: alpar@1043: template alpar@1043: T listsort(typename T::iterator b, typename T::iterator e) alpar@1092: { alpar@1043: if(b==e) return T(); alpar@1043: typename T::iterator bn=b; alpar@1043: if(++bn==e) { alpar@1043: T l; alpar@1043: l.push_back(*b); alpar@1043: return l; alpar@1043: } alpar@1043: typename T::iterator m=b; alpar@1043: bool x=false; alpar@1043: for(typename T::iterator i=b;i!=e;++i,x=!x) alpar@1043: if(x) ++m; alpar@1043: T l1(listsort(b,m)); alpar@1043: T l2(listsort(m,e)); alpar@1043: T l; alpar@1043: while((!l1.empty())&&(!l2.empty())) alpar@1043: if(l1.front()<=l2.front()) alpar@1043: { alpar@1043: l.push_back(l1.front()); alpar@1043: l1.pop_front(); alpar@1043: } alpar@1043: else { alpar@1043: l.push_back(l2.front()); alpar@1043: l2.pop_front(); alpar@1043: } alpar@1043: while(!l1.empty()) alpar@1043: { alpar@1043: l.push_back(l1.front()); alpar@1043: l1.pop_front(); alpar@1043: } alpar@1043: while(!l2.empty()) alpar@1043: { alpar@1043: l.push_back(l2.front()); alpar@1043: l2.pop_front(); alpar@1043: } alpar@1043: return l; alpar@1043: } alpar@1043: alpar@1043: template alpar@1043: void generateIntSequence(int n, T & data) { deba@441: int prime = 9973; deba@441: int root = 136, value = 1; deba@441: for (int i = 0; i < n; ++i) { deba@441: data.push_back(value - prime / 2); deba@441: value = (value * root) % prime; deba@441: } deba@441: } deba@441: alpar@1043: template alpar@1043: void generateCharSequence(int n, T & data) { deba@441: int prime = 251; deba@441: int root = 3, value = root; deba@441: for (int i = 0; i < n; ++i) { deba@441: data.push_back(static_cast(value)); deba@441: value = (value * root) % prime; deba@441: } deba@441: } deba@441: deba@441: void checkRadixSort() { deba@441: { deba@441: std::vector data1; deba@441: generateIntSequence(n, data1); deba@441: deba@441: std::vector data2(data1); deba@441: std::sort(data1.begin(), data1.end()); deba@441: deba@441: radixSort(data2.begin(), data2.end()); deba@441: for (int i = 0; i < n; ++i) { deba@441: check(data1[i] == data2[i], "Test failed"); deba@441: } deba@441: alpar@1043: // radixSort(data2.begin(), data2.end(), Negate()); alpar@1043: // for (int i = 0; i < n; ++i) { alpar@1043: // check(data1[i] == data2[n - 1 - i], "Test failed"); alpar@1043: // } deba@441: alpar@1043: // radixSort(data2.begin(), data2.end(), negate); alpar@1043: // for (int i = 0; i < n; ++i) { alpar@1043: // check(data1[i] == data2[n - 1 - i], "Test failed"); alpar@1043: // } deba@441: alpar@442: } alpar@442: deba@441: { deba@441: std::vector data1(n); deba@441: generateCharSequence(n, data1); deba@441: deba@441: std::vector data2(data1); deba@441: std::sort(data1.begin(), data1.end()); deba@441: deba@441: radixSort(data2.begin(), data2.end()); deba@441: for (int i = 0; i < n; ++i) { deba@441: check(data1[i] == data2[i], "Test failed"); deba@441: } deba@441: deba@441: } alpar@1043: { alpar@1043: std::list data1; alpar@1043: generateIntSequence(n, data1); alpar@1043: alpar@1043: std::list data2(listsort >(data1.begin(), data1.end())); alpar@1043: alpar@1043: radixSort(data1.begin(), data1.end()); alpar@1043: alpar@1043: check(isTheSame(data1,data2), "Test failed"); alpar@1043: alpar@1043: alpar@1043: // radixSort(data2.begin(), data2.end(), Negate()); alpar@1043: // check(isTheSame(data1,data2), "Test failed"); alpar@1043: // for (int i = 0; i < n; ++i) { alpar@1043: // check(data1[i] == data2[n - 1 - i], "Test failed"); alpar@1043: // } alpar@1043: alpar@1043: // radixSort(data2.begin(), data2.end(), negate); alpar@1043: // for (int i = 0; i < n; ++i) { alpar@1043: // check(data1[i] == data2[n - 1 - i], "Test failed"); alpar@1043: // } alpar@1043: alpar@1043: } alpar@1043: alpar@1043: { alpar@1043: std::list data1(n); alpar@1043: generateCharSequence(n, data1); alpar@1043: alpar@1043: std::list data2(listsort > alpar@1043: (data1.begin(), alpar@1043: data1.end())); alpar@1043: alpar@1043: radixSort(data1.begin(), data1.end()); alpar@1043: check(isTheSame(data1,data2), "Test failed"); alpar@1043: alpar@1043: } deba@441: } deba@441: deba@441: deba@443: void checkStableRadixSort() { deba@441: { deba@441: std::vector data1; deba@441: generateIntSequence(n, data1); deba@441: deba@441: std::vector data2(data1); deba@441: std::sort(data1.begin(), data1.end()); deba@441: deba@443: stableRadixSort(data2.begin(), data2.end()); deba@441: for (int i = 0; i < n; ++i) { deba@441: check(data1[i] == data2[i], "Test failed"); deba@441: } deba@441: deba@443: stableRadixSort(data2.begin(), data2.end(), Negate()); deba@441: for (int i = 0; i < n; ++i) { deba@441: check(data1[i] == data2[n - 1 - i], "Test failed"); deba@441: } deba@441: deba@443: stableRadixSort(data2.begin(), data2.end(), negate); deba@441: for (int i = 0; i < n; ++i) { deba@441: check(data1[i] == data2[n - 1 - i], "Test failed"); deba@441: } alpar@442: } deba@441: deba@441: { deba@441: std::vector data1(n); deba@441: generateCharSequence(n, data1); deba@441: deba@441: std::vector data2(data1); deba@441: std::sort(data1.begin(), data1.end()); deba@441: deba@441: radixSort(data2.begin(), data2.end()); deba@441: for (int i = 0; i < n; ++i) { deba@441: check(data1[i] == data2[i], "Test failed"); deba@441: } deba@441: deba@441: } alpar@1043: { alpar@1043: std::list data1; alpar@1043: generateIntSequence(n, data1); alpar@1043: alpar@1043: std::list data2(listsort >(data1.begin(), alpar@1043: data1.end())); alpar@1043: stableRadixSort(data1.begin(), data1.end()); alpar@1043: check(isTheSame(data1,data2), "Test failed"); alpar@1043: alpar@1043: // stableRadixSort(data2.begin(), data2.end(), Negate()); alpar@1043: // for (int i = 0; i < n; ++i) { alpar@1043: // check(data1[i] == data2[n - 1 - i], "Test failed"); alpar@1043: // } alpar@1043: alpar@1043: // stableRadixSort(data2.begin(), data2.end(), negate); alpar@1043: // for (int i = 0; i < n; ++i) { alpar@1043: // check(data1[i] == data2[n - 1 - i], "Test failed"); alpar@1043: // } alpar@1043: } alpar@1043: alpar@1043: { alpar@1043: std::list data1(n); alpar@1043: generateCharSequence(n, data1); alpar@1043: alpar@1043: std::list data2(listsort > alpar@1043: (data1.begin(), alpar@1043: data1.end())); alpar@1043: radixSort(data1.begin(), data1.end()); alpar@1043: check(isTheSame(data1,data2), "Test failed"); alpar@1043: alpar@1043: } deba@441: } deba@441: deba@441: int main() { deba@441: alpar@442: checkRadixSort(); deba@443: checkStableRadixSort(); deba@441: deba@441: return 0; deba@441: }