⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 garandom.cpp

📁 遗传算法工具箱C++
💻 CPP
字号:
// $Header$/* ----------------------------------------------------------------------------random.Cmbwall 5sep95Copyright (c) 1995 Massachusetts Institute of Technologyall rights reservedDESCRIPTION:Random number stuff for use in GAlib.---------------------------------------------------------------------------- */#include "garandom.h"#include <time.h>#include <math.h>#include <string.h>static void bitseed(unsigned int seed=1);// If the machine has multiple processes, use the PID to help make the random// number generator seed more random.#if defined(GALIB_USE_PID)#include <unistd.h>#define _GA_PID * getpid()#else#define _GA_PID#endif// Return a string indicating which random number generator was compiled-in to// the library.const char*GAGetRNG() {#if defined(GALIB_USE_RAN1)	return "RAN1";#elif defined(GALIB_USE_RAN2)	return "RAN2";#elif defined(GALIB_USE_RAN3)	return "RAN3";#elif defined(GALIB_USE_RAND)	return "RAND";#elif defined(GALIB_USE_RANDOM)	return "RANDOM";#elif defined(GALIB_USE_RAND48)	return "RAND48";#else	return "UNKNOWN";#endif}// Seed the random number generator with an appropriate value.  We seed both // the random number generator and the random bit generator.  Set the seed only// if a seed is not specified.  If a seed is specified, then set the seed to // the specified value and use it.  We remember the seed so that multiple calls// to this function with the same seed do not reset the generator.  Subsequent// calls to this function with a different seed will initialize the generator// to the new seed.  Multiple calls with a value of 0 do nothing (we do *not*// re-seed the generator because 0 is the default value and we don't want // people to re-seed the generator inadvertantly).//   Some systems return a long as the return value for time, so we need to be// sure to get whatever variation from it that we can since our seed is only an// unsigned int.static unsigned int seed=0;unsigned int GAGetRandomSeed() { return seed; }void GARandomSeed(unsigned int s) {	if(s == 0 && seed == 0) {		unsigned long int tmp;		while(seed == 0) {			tmp = time(NULL) _GA_PID;			for(unsigned int i=0; i<GALIB_BITS_IN_WORD*sizeof(unsigned int); i++)				seed += (tmp & (1 << i));		}		_GA_RND_SEED (seed); 		bitseed(seed);	}	else if(s != 0 && seed != s) {		seed = s;		_GA_RND_SEED (seed); 		bitseed(seed);	}}// Similar to setting the random seed, but this one sets it as long as the// specified seed is non-zero.voidGAResetRNG(unsigned int s) {	if(s != 0) {		seed = s;		_GA_RND_SEED (seed); 		bitseed(seed);	}}// Return a number from a unit Gaussian distribution.  The mean is 0 and the// standard deviation is 1.0.//   First we generate two uniformly random variables inside the complex unit // circle.  Then we transform these into Gaussians using the Box-Muller // transformation.  This method is described in Numerical Recipes in C // ISBN 0-521-43108-5 at http://world.std.com/~nr//   When we find a number, we also find its twin, so we cache that here so // that every other call is a lookup rather than a calculation.  (I think GNU // does this in their implementations as well, but I don't remember for // certain.)doubleGAUnitGaussian(){	static GABoolean cached=gaFalse;	static double cachevalue;	if(cached == gaTrue){		cached = gaFalse;		return cachevalue;	}	double rsquare, factor, var1, var2;	do{		var1 = 2.0 * GARandomDouble() - 1.0;		var2 = 2.0 * GARandomDouble() - 1.0;		rsquare = var1*var1 + var2*var2;	} while(rsquare >= 1.0 || rsquare == 0.0);	double val = -2.0 * log(rsquare) / rsquare;	if(val > 0.0) factor = sqrt(val);	else           factor = 0.0;	// should not happen, but might due to roundoff	cachevalue = var1 * factor;	cached = gaTrue;	return (var2 * factor);}// This is the random bit generator Method II from numerical recipes in C.  The// seed determines where in the cycle of numbers the generator will start, so// we don't need full 'long' precision in the argument to the seed function.#define IB1 1#define IB2 2#define IB5 16#define IB18 131072L#define MASK (IB1+IB2+IB5)static unsigned long iseed;void bitseed(unsigned int seed) {	iseed = seed;}int GARandomBit() {	if (iseed & IB18) {		iseed=((iseed ^ MASK) << 1) | IB1;		return 1;	} else {		iseed <<= 1;		return 0;	}}#undef MASK#undef IB18#undef IB5#undef IB2#undef IB1// The following random number generators are from Numerical Recipes in C.// I have split them into a seed function and random number function.// The ran1 pseudo-random number generator.  This one is OK to use as long as// you don't call it more than about 10^8 times, so for any long GA runs you'd// better use something with a longer period.#if defined(GALIB_USE_RAN1)#define IA 16807L#define IM 2147483647L#define AM (1.0/IM)#define IQ 127773L#define IR 2836L#define NTAB 32#define NDIV (1+(IM-1)/NTAB)#define EPS 1.2e-7#define RNMX (1.0-EPS)static long iy=0;static long iv[NTAB];static long idum=0;voidgasran1(unsigned int seed) {	int j;	long k;	idum = seed;	if (idum == 0) idum=1;	if (idum < 0) idum = -idum;	for (j=NTAB+7;j>=0;j--) {		k=(idum)/IQ;		idum=IA*(idum-k*IQ)-IR*k;		if (idum < 0) idum += IM;		if (j < NTAB) iv[j] = idum;	}	iy=iv[0];}float garan1() {	int j;	long k;	float temp;	k=(idum)/IQ;	idum=IA*(idum-k*IQ)-IR*k;	if (idum < 0) idum += IM;	j=iy/NDIV;	iy=iv[j];	iv[j] = idum;	if ((temp=AM*iy) > RNMX) return RNMX;	else return temp;}#undef IA#undef IM#undef AM#undef IQ#undef IR#undef NTAB#undef NDIV#undef EPS#undef RNMX#endif// The ran2 pseudo-random number generator.  It has a period of 2 * 10^18 and// returns a uniform random deviate on the interval (0.0, 1.0) excluding the// end values.  idum initializes the sequence, so we create a separate seeding// function to set the seed.  If you reset the seed then you re-initialize the// sequence.#if defined(GALIB_USE_RAN2)#define IM1 2147483563L#define IM2 2147483399L#define AM (1.0/IM1)#define IMM1 (IM1-1)#define IA1 40014L#define IA2 40692L#define IQ1 53668L#define IQ2 52774L#define IR1 12211L#define IR2 3791#define NTAB 32#define NDIV (1+IMM1/NTAB)#define EPS 1.2e-7#define RNMX (1.0-EPS)static long idum2=123456789;static long iy=0;static long iv[NTAB];static long idum=0;void gasran2(unsigned int seed) {	int j;	long k;	idum = STA_CAST(long,seed);	if (idum == 0) idum=1;	if (idum < 0) idum = -idum;	idum2=(idum);	for (j=NTAB+7;j>=0;j--) {		k=(idum)/IQ1;		idum=IA1*(idum-k*IQ1)-k*IR1;		if (idum < 0) idum += IM1;		if (j < NTAB) iv[j] = idum;	}	iy=iv[0];}float garan2() {	int j;	long k;	//float temp;	float temp;	k=(idum)/IQ1;	idum=IA1*(idum-k*IQ1)-k*IR1;	if (idum < 0) idum += IM1;	k=idum2/IQ2;	idum2=IA2*(idum2-k*IQ2)-k*IR2;	if (idum2 < 0) idum2 += IM2;	j=iy/NDIV;	iy=iv[j]-idum2;	iv[j] = idum;	if (iy < 1) iy += IMM1;	if ((temp=AM*iy) > RNMX) return RNMX;	else return temp;}#undef IM1#undef IM2#undef AM#undef IMM1#undef IA1#undef IA2#undef IQ1#undef IQ2#undef IR1#undef IR2#undef NTAB#undef NDIV#undef EPS#undef RNMX#endif#if defined(GALIB_USE_RAN3)// The ran3 pseudo-random number generator.  It is *not* linear congruential.#define MBIG 1000000000#define MSEED 161803398#define MZ 0#define FAC (1.0/MBIG)static int inext,inextp;static long ma[56];void gasran3(unsigned int seed) {	long idum = seed;	long mj,mk;	int i,ii,k;	mj=labs(MSEED-labs(idum));	mj %= MBIG;	ma[55]=mj;	mk=1;	for (i=1;i<=54;i++) {		ii=(21*i) % 55;		ma[ii]=mk;		mk=mj-mk;		if (mk < MZ) mk += MBIG;		mj=ma[ii];	}	for (k=1;k<=4;k++)		for (i=1;i<=55;i++) {			ma[i] -= ma[1+(i+30) % 55];			if (ma[i] < MZ) ma[i] += MBIG;		}		inext=0;		inextp=31;}float garan3() {	long mj;	int i,ii,k;	if (++inext == 56) inext=1;	if (++inextp == 56) inextp=1;	mj=ma[inext]-ma[inextp];	if (mj < MZ) mj += MBIG;	ma[inext]=mj;	return mj*FAC;}#undef MBIG#undef MSEED#undef MZ#undef FAC#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -