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

📄 rng.cpp

📁 粗糙集应用软件
💻 CPP
字号:
//-------------------------------------------------------------------
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Revisions.....:
//===================================================================

#include <stdafx.h> // Precompiled headers.
#include <copyright.h>

#include <kernel/utilities/rng.h>
#include <kernel/utilities/mathkit.h>

//-------------------------------------------------------------------
// Static methods (file scope).
//===================================================================

//-------------------------------------------------------------------
// Method........: ran1
// Author........:
// Date..........:
// Description...: "Minimal" random number generator of Park and Miller
//                 with Bays-Durham shuffle and added safeguards.
//                 Returns a uniform random deviate between 0.0 and 1.0
//                 (exclusive of the endpoint values). Call with idum
//                 a negative integer to initialize; thereafter, do not
//                 alter idum between successive deviates in a sequence.
//                 RNMX should approximate the largest floating value that
//                 is less than 1.
//
// Comments......: Taken from the book "Numerical Recipes in C".
// Revisions.....:
//===================================================================

static float
ran1(long *idum) {

	const long   IA     = 16807;
	const long   IM     = 2147483647;
	const double AM     = (1.0 / IM);
	const long   IQ     = 127773;
	const long   IR     = 2836;
	const long   NTAB   = 32;
  const long   NDIV   = (1 + (IM - 1) / NTAB);
	const double EPS    = 1.2e-7;
	const double RNMX   = (1.0 - EPS);

	int         j;
	long        k;
	static long iy = 0;
	static long iv[NTAB];
	float       temp;

	if (*idum <= 0 || !iy) {                // Initialize.
		if (-(*idum) < 1)
			*idum = 1;                          // Be sure to prevent idum = 0.
		else
			*idum = -(*idum);
		for (j = NTAB + 7; j >=0; j--) {      // Load the shuffle table (after 8 warm-ups).
			k = (*idum) / IQ;
			*idum = IA * (*idum - k * IQ) - IR * k;
			if (*idum < 0)
				*idum += IM;
			if (j < NTAB)
				iv[j] = *idum;
		}
		iy = iv[0];
	}
	k = (*idum) / IQ;                       // Start here when not initializing.
	*idum = IA * (*idum - k * IQ) - IR * k; // Compute idum = (IA * idum) % IM without overflows by Schrage's method.
	if (*idum < 0)
		*idum += IM;
	j = iy / NDIV;                          // Will be in the range 0..NTAB-1.
	iy = iv[j];                             // Output previously stored value and refill the shuffle table.
	iv[j] = *idum;
	if ((temp = AM * iy) > RNMX)
		return RNMX;                          // Because users don't expect endpoint values.
	else
		return temp;
}

//-------------------------------------------------------------------
// Methods for class RNG.
//===================================================================

//-------------------------------------------------------------------
// Constructors/destructor.
//===================================================================

RNG::RNG() {
	SetSeed(-1);
}

RNG::RNG(long seed) {
	SetSeed(seed);
}

RNG::~RNG() {
}

//-------------------------------------------------------------------
// Method........: GetSeed
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================

long
RNG::GetSeed() const {
	return seed_;
}

//-------------------------------------------------------------------
// Method........: SetSeed
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================

void
RNG::SetSeed(long seed) {

	seed_ = seed;

	if (seed < 0)
		idum_ = seed;
	else if (seed > 0)
		idum_ = -seed;
	else
		idum_ = -1;

	ran1(&idum_);

}

//-------------------------------------------------------------------
// Method........: DrawFloat
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns a float in the range (lower, upper),
//                 sampled from a uniform distribution.
// Comments......:
// Revisions.....:
//===================================================================

float
RNG::DrawFloat(float lower, float upper) const {

	if (lower == upper)
		return lower;

	// This method is conceptually const only.
	RNG *self = const_cast(RNG *, this);

	// Draw (0, 1) deviate.
	float deviate = ran1(&(self->idum_));

	// Swap order?
	if (lower > upper) {
		float tmp = lower;
		lower = upper;
		upper = lower;
	}

	if (lower == 0.0 && upper == 1.0)
		return deviate;

	// Rescale.
	deviate *= upper - lower;
	deviate += lower;

	return deviate;

}

//-------------------------------------------------------------------
// Method........: DrawInteger
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns an integer in the range [lower, upper],
//                 sampled from a uniform distribution.
// Comments......: Expanded range with 0.49 in both ends so that the
//                 endpoints will appear with the expected frequency.
// Revisions.....:
//===================================================================

int
RNG::DrawInteger(int lower, int upper) const {
	return MathKit::Round(DrawFloat(lower - 0.49f, upper + 0.49f));
}


⌨️ 快捷键说明

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