Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "RandomLib/Random.hpp"
00030 #include <iostream>
00031 #include <iomanip>
00032 #include <sstream>
00033 #include <vector>
00034
00035 #define RANDOMPERMUTATION_CPP "$Id: RandomPermutation.cpp 6723 2010-01-11 14:20:10Z ckarney $"
00036 RCSID_DECL(RANDOMPERMUTATION_CPP)
00037
00038 void usage(const std::string name, int retval) {
00039 ( retval == 0 ? std::cout : std::cerr )
00040 << "Usage: " << name
00041 << " [-o] [-d] [-x] [-s seed] [-v] [-r] [-h] [num]\n\
00042 \n\
00043 Print a random permutation of numbers from 0 thru num-1\n\
00044 on standard output. num is supplied on the command line\n\
00045 as a decimal number (default is 100). Optional arguments\n\
00046 -o, -d, and -x selection octal, decimal, and hexadecimal\n\
00047 output base (default decimal). -s seed sets the seed.\n\
00048 -v prints seed on standard error. -h prints this help.\n";
00049 exit(retval);
00050 }
00051
00052 int main(int argc, char* argv[]) {
00053 try{
00054 unsigned n = 100;
00055 unsigned base = 10;
00056 bool verbose = false;
00057 bool seedgiven = false;
00058 bool reverse = false;
00059 std::string seed;
00060 std::string arg;
00061 int m = 0;
00062 while (++m < argc) {
00063 arg = std::string(argv[m]);
00064 if (arg[0] != '-')
00065 break;
00066 if (arg == "-o")
00067 base = 8;
00068 else if (arg == "-d")
00069 base = 10;
00070 else if (arg == "-x")
00071 base = 16;
00072 else if (arg == "-v")
00073 verbose = true;
00074 else if (arg == "-r")
00075 reverse = true;
00076 else if (arg == "-s") {
00077 seedgiven = true;
00078 if (++m == argc)
00079 usage(argv[0], 1);
00080 seed = std::string(argv[m]);
00081 } else if (arg == "-h")
00082 usage(argv[0], 0);
00083 else
00084 usage(argv[0], 1);
00085 }
00086 if (m == argc - 1) {
00087 std::istringstream str(arg);
00088 str >> n;
00089 } else if (m != argc)
00090 usage(argv[0], 1);
00091
00092 unsigned k = 0;
00093 for (unsigned i = n - 1; i; i /= base) k++;
00094
00095 std::vector<unsigned> a(n);
00096 for (unsigned i = n; i--;) a[i] = i;
00097
00098 RandomLib::Random r = seedgiven ? RandomLib::Random(seed) :
00099 RandomLib::Random(RandomLib::Random::SeedVector());
00100 if (verbose)
00101 std::cerr << "Seed: " << r.SeedString() << "\n";
00102 std::random_shuffle(a.begin(), a.end(), r);
00103
00104 if (reverse) {
00105 std::vector< std::pair<unsigned, unsigned> > b(n);
00106 for (unsigned i = n; i--;) b[i] = std::pair<unsigned, unsigned>(a[i], i);
00107 std::sort(b.begin(), b.end());
00108
00109 for (unsigned i = n; i--;) a[i] = n - 1 - b[n - 1 - i].second;
00110 }
00111
00112 std::cout << std::setfill('0')
00113 << (base == 16 ? std::hex : (base == 8 ? std::oct : std::dec));
00114 for (unsigned i = n; i--;)
00115 std::cout << std::setw(k) << a[i] << "\n";
00116
00117 return 0;
00118 }
00119 catch (...) {
00120 std::cerr << "Unexpected error" << "\n";
00121 }
00122 }