00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #if defined(__GNUC__) && defined(__linux__)
00015 # include <linux/limits.h>
00016 #endif
00017 #if defined(_MSC_VER)
00018 # include <windows.h>
00019 # define PATH_MAX 4096
00020 #else
00021 # include <sys/time.h>
00022 #endif
00023
00024 #include <cstring>
00025 #include <ctime>
00026
00027 #include "base/hash.h"
00028 #include "base/random.h"
00029
00030 namespace operations_research {
00031
00032 int32 ACMRandom::Next() {
00033 if (seed_ == 0) {
00034 seed_ = 0x14fd4603;
00035 }
00036 const int32 M = 2147483647L;
00037 const int32 A = 16807;
00038
00039 uint32 lo = A * static_cast<int32>(seed_ & 0xFFFF);
00040 uint32 hi = A * static_cast<int32>(static_cast<uint32>(seed_) >> 16);
00041 lo += (hi & 0x7FFF) << 16;
00042 if (lo > M) {
00043 lo &= M;
00044 ++lo;
00045 }
00046 lo += hi >> 15;
00047 if (lo > M) {
00048 lo &= M;
00049 ++lo;
00050 }
00051 return (seed_ = static_cast<int32>(lo));
00052 }
00053
00054 int32 ACMRandom::Uniform(int32 n) {
00055 return Next() % n;
00056 }
00057
00058 int64 ACMRandom::Next64() {
00059 const int64 next = Next();
00060 return (next - 1) * 2147483646L + Next();
00061 }
00062
00063 namespace {
00064 static inline uint32 Word32At(const char *ptr) {
00065 return ((static_cast<uint32>(ptr[0])) +
00066 (static_cast<uint32>(ptr[1]) << 8) +
00067 (static_cast<uint32>(ptr[2]) << 16) +
00068 (static_cast<uint32>(ptr[3]) << 24));
00069 }
00070 }
00071
00072 int32 ACMRandom::HostnamePidTimeSeed() {
00073 char name[PATH_MAX + 20];
00074 assert(sizeof(name) - PATH_MAX > sizeof(uint32) * 3);
00075
00076 if (gethostname(name, PATH_MAX) != 0) {
00077 strcpy(name, "default-hostname");
00078 }
00079 const int namelen = strlen(name);
00080 for (int i = 0; i < sizeof(uint32) * 3; ++i) {
00081 name[namelen + i] = '\0';
00082 }
00083 #if defined(__GNUC__)
00084 uint32 a = getpid();
00085 struct timeval tv;
00086 gettimeofday(&tv, NULL);
00087 uint32 b = static_cast<uint32>((tv.tv_sec + tv.tv_usec) & 0xffffffff);
00088 #elif defined(_MSC_VER)
00089 uint32 a = GetCurrentProcessId();
00090 uint32 b = GetTickCount();
00091 #else // Do not know what to do, returning 0.
00092 return 0;
00093 #endif
00094 uint32 c = 0;
00095 for (int i = 0; i < namelen; i += sizeof(uint32) * 3) {
00096 a += Word32At(name + i);
00097 b += Word32At(name + i + sizeof(uint32));
00098 c += Word32At(name + i + sizeof(uint32) + sizeof(uint32));
00099 mix(a, b, c);
00100 }
00101 c += namelen;
00102 mix(a,b,c);
00103 return static_cast<int32>(c);
00104 }
00105
00106 int32 ACMRandom::DeterministicSeed() { return 0; }
00107
00108 }