Basic math Q: how do I make a number-generation function that is biased toward a specified numeric

K

Ken Fine

Hi there,

I have written a simple function that attempts to set the angle of objects
so as to place them in aesthetically appealing ways. The code follows; there
is some stupidness in it (e.g. a test for meaningless <=180 as a boolean
test). The function is designed to return values that will avoid positioning
things a) upside down and b) at "too steep" an angle.

I would now like to know how I could write my function so that the machine
would pick semi-random numbers, but so that those numbers would be biased
toward a prespecified value. Ideally it could be parameterized such that you
could choose (for lack of a better term) a "gravity" setting. In other
words, there would be paramaterized "knob" that indicated how willing you
were to let the numbers deviate from your prespecified center value. Low
"gravity" would let the numbers float all over the place, with only slight
bias. High gravity would bias the selection very strongly toward the center.
This would be useful in all sorts of ways.

I should have paid more attention in math class. Can someone offer a
suggestion? Code follows.

private int GetRandomAngle()
{
Random rand = this.Session["MyRandom"] as Random;
int rand1= rand.Next(0, 360);
if (rand1 >= 180)
{
return(rand.Next(270,360));

}
if (rand1 <=180)
{
return(rand.Next(10, 70));

}
return (rand.Next(280, 340));
}
 
G

Guest

Start with an initial value Xi.

Obtain a random number R between 0 and 1. Subtract Y: Y=0.5 gives a non
biased multiplier, <0.5 gives a positive biased multiplier, >0.5 gives a
negative bias multiplier. Gravity=(R+Y)

New Value = Xi + (R-Y)(Increment)
 
G

Guest

sorry, that's gravity=R-Y


mr peanut said:
Start with an initial value Xi.

Obtain a random number R between 0 and 1. Subtract Y: Y=0.5 gives a non
biased multiplier, <0.5 gives a positive biased multiplier, >0.5 gives a
negative bias multiplier. Gravity=(R+Y)

New Value = Xi + (R-Y)(Increment)




Ken Fine said:
Hi there,

I have written a simple function that attempts to set the angle of objects
so as to place them in aesthetically appealing ways. The code follows; there
is some stupidness in it (e.g. a test for meaningless <=180 as a boolean
test). The function is designed to return values that will avoid positioning
things a) upside down and b) at "too steep" an angle.

I would now like to know how I could write my function so that the machine
would pick semi-random numbers, but so that those numbers would be biased
toward a prespecified value. Ideally it could be parameterized such that you
could choose (for lack of a better term) a "gravity" setting. In other
words, there would be paramaterized "knob" that indicated how willing you
were to let the numbers deviate from your prespecified center value. Low
"gravity" would let the numbers float all over the place, with only slight
bias. High gravity would bias the selection very strongly toward the center.
This would be useful in all sorts of ways.

I should have paid more attention in math class. Can someone offer a
suggestion? Code follows.

private int GetRandomAngle()
{
Random rand = this.Session["MyRandom"] as Random;
int rand1= rand.Next(0, 360);
if (rand1 >= 180)
{
return(rand.Next(270,360));

}
if (rand1 <=180)
{
return(rand.Next(10, 70));

}
return (rand.Next(280, 340));
}
 
R

rossum

Hi there,

I have written a simple function that attempts to set the angle of objects
so as to place them in aesthetically appealing ways. The code follows; there
is some stupidness in it (e.g. a test for meaningless <=180 as a boolean
test). The function is designed to return values that will avoid positioning
things a) upside down and b) at "too steep" an angle.

I would now like to know how I could write my function so that the machine
would pick semi-random numbers, but so that those numbers would be biased
toward a prespecified value. Ideally it could be parameterized such that you
could choose (for lack of a better term) a "gravity" setting. In other
words, there would be paramaterized "knob" that indicated how willing you
were to let the numbers deviate from your prespecified center value. Low
"gravity" would let the numbers float all over the place, with only slight
bias. High gravity would bias the selection very strongly toward the center.
This would be useful in all sorts of ways.

I should have paid more attention in math class. Can someone offer a
suggestion? Code follows.

private int GetRandomAngle()
{
Random rand = this.Session["MyRandom"] as Random;
int rand1= rand.Next(0, 360);
if (rand1 >= 180)
{
return(rand.Next(270,360));

}
if (rand1 <=180)
{
return(rand.Next(10, 70));

}
return (rand.Next(280, 340));
}
Most random number generators generate a "flat" output - each number
in the selected range is equally probable. You seem to want a
"humped" output with a bias towards the middle.

A single die gives a flat 1 - 6, while two dice give a humped 2 - 12
(with the hump at 7). So using that as a model you can use your flat
generator repeatedly and divide to get a humped distribution biased
towards the centre.

Something like:

private int getRandomBias(int middle, int spread) {
int result = 0;
int repetitions = 3;
for (int i = 0; i < repetitions; ++i) {
result += rand.Next(middle - spread, middle + spread);
}
return result / repetitions;
}

The higher the value of repetitions the more pointed the distribution
will be. You can experiment to get the effect you want.

rossum
 
K

Ken Fine

Thank you, Mr. Peanut. I have written what I think is a function that
follows your math, but I think I'm missing something. What exactly is
"increment" in this case?

Here is my nonfunctional function: it does something ;) but it doesn't seem
to be working in the way it should be:

private double GetBiasedAngle(int centerAngle, double biasValue, double
increment)

{
Random rand = this.Session["MyRandom"] as Random;
double myrandom = rand.NextDouble();
double biasedAngle = centerAngle + ((myrandom - biasValue)*increment);
double finalAngle = Convert.ToInt32(biasedAngle);
return finalAngle;
}

Thanks again for your help and explanation.

-KF

mr peanut said:
sorry, that's gravity=R-Y


mr peanut said:
Start with an initial value Xi.

Obtain a random number R between 0 and 1. Subtract Y: Y=0.5 gives a non
biased multiplier, <0.5 gives a positive biased multiplier, >0.5 gives a
negative bias multiplier. Gravity=(R+Y)

New Value = Xi + (R-Y)(Increment)




Ken Fine said:
Hi there,

I have written a simple function that attempts to set the angle of
objects
so as to place them in aesthetically appealing ways. The code follows;
there
is some stupidness in it (e.g. a test for meaningless <=180 as a
boolean
test). The function is designed to return values that will avoid
positioning
things a) upside down and b) at "too steep" an angle.

I would now like to know how I could write my function so that the
machine
would pick semi-random numbers, but so that those numbers would be
biased
toward a prespecified value. Ideally it could be parameterized such
that you
could choose (for lack of a better term) a "gravity" setting. In other
words, there would be paramaterized "knob" that indicated how willing
you
were to let the numbers deviate from your prespecified center value.
Low
"gravity" would let the numbers float all over the place, with only
slight
bias. High gravity would bias the selection very strongly toward the
center.
This would be useful in all sorts of ways.

I should have paid more attention in math class. Can someone offer a
suggestion? Code follows.

private int GetRandomAngle()
{
Random rand = this.Session["MyRandom"] as Random;
int rand1= rand.Next(0, 360);
if (rand1 >= 180)
{
return(rand.Next(270,360));

}
if (rand1 <=180)
{
return(rand.Next(10, 70));

}
return (rand.Next(280, 340));
}
 
K

Ken Fine

Thanks rossum, for the code, the model, and the clear discussion.

-KF



rossum said:
Hi there,

I have written a simple function that attempts to set the angle of objects
so as to place them in aesthetically appealing ways. The code follows;
there
is some stupidness in it (e.g. a test for meaningless <=180 as a boolean
test). The function is designed to return values that will avoid
positioning
things a) upside down and b) at "too steep" an angle.

I would now like to know how I could write my function so that the machine
would pick semi-random numbers, but so that those numbers would be biased
toward a prespecified value. Ideally it could be parameterized such that
you
could choose (for lack of a better term) a "gravity" setting. In other
words, there would be paramaterized "knob" that indicated how willing you
were to let the numbers deviate from your prespecified center value. Low
"gravity" would let the numbers float all over the place, with only slight
bias. High gravity would bias the selection very strongly toward the
center.
This would be useful in all sorts of ways.

I should have paid more attention in math class. Can someone offer a
suggestion? Code follows.

private int GetRandomAngle()
{
Random rand = this.Session["MyRandom"] as Random;
int rand1= rand.Next(0, 360);
if (rand1 >= 180)
{
return(rand.Next(270,360));

}
if (rand1 <=180)
{
return(rand.Next(10, 70));

}
return (rand.Next(280, 340));
}
Most random number generators generate a "flat" output - each number
in the selected range is equally probable. You seem to want a
"humped" output with a bias towards the middle.

A single die gives a flat 1 - 6, while two dice give a humped 2 - 12
(with the hump at 7). So using that as a model you can use your flat
generator repeatedly and divide to get a humped distribution biased
towards the centre.

Something like:

private int getRandomBias(int middle, int spread) {
int result = 0;
int repetitions = 3;
for (int i = 0; i < repetitions; ++i) {
result += rand.Next(middle - spread, middle + spread);
}
return result / repetitions;
}

The higher the value of repetitions the more pointed the distribution
will be. You can experiment to get the effect you want.

rossum
 
P

Peter Duniho

Ken said:
I would now like to know how I could write my function so that the
machine would pick semi-random numbers, but so that those numbers would
be biased toward a prespecified value. Ideally it could be parameterized
such that you could choose (for lack of a better term) a "gravity"
setting. In other words, there would be paramaterized "knob" that
indicated how willing you were to let the numbers deviate from your
prespecified center value. Low "gravity" would let the numbers float all
over the place, with only slight bias. High gravity would bias the
selection very strongly toward the center. This would be useful in all
sorts of ways.

I should have paid more attention in math class.

Yes, you should have. :)
Can someone offer a suggestion? Code follows.

The code you posted is unclear to me. Does it do something even similar
to what you want? You don't even have a way for the last statement in
the method to be executed (rand1 is always going to either be >= 180 or
<= 180, so one or the other if() statements will always be true).

Anyway, for starters you may want to read these articles:

http://en.wikipedia.org/wiki/Statistical_distribution
http://en.wikipedia.org/wiki/Normal_distribution

As you may notice, the question you asked is perhaps a lot more
complicated than you might have guessed. :)

You've gotten a couple of answers so far, but it's not clear from your
original post that they are necessarily the answers you're looking for.

The first, from "mr peanut", does not produce a normal distribution (ie
"bell curve"). It will produce a linear distribution, with the range of
width "Increment" shifted relative to "Xi" according to what he calls
"gravity". You could accomplish the same simply by picking appropriate
boundaries to pass to the Random.Next() method.

The second, from "rossum", produces a quasi-normal distribution (that
is, as the number of repetitions goes up, the resulting distribution of
random numbers is increasingly closer to an actual normal distribution).
However, you don't get very much control of the "gravity" aspect.
That is, one repetition gives you linear distribution, two jumps to a
triangular-shaped distribution, and three or more starts to approximate
an exact normal distribution.

So, you can cluster the numbers more closely to the center by adding
repititions, but the returns from this method quickly diminish. The
exact normal distribution will never on its own cluster tightly to the
center, because it has a very specific shape.

Whether you use an approximate or exact generation method for normal
distribution
(http://en.wikipedia.org/wiki/Normal_distribution#Generating_values_for_normal_random_variables)
you'll run into this issue. You can address it partially by changing
the range across which the distribution is generated; the smaller the
range, the more the "gravity". But doing so necessarily excludes any
possible occurrence of the farther ranges.

For example, suppose you start with a normal distribution centered at 90
degrees, ranging from 0 to 180. You can tighten this up by decreasing
the range to be between 45 and 135, but then you will never see values
less than 45 or greater than 135.

Whether that's a problem or not isn't clear from your post. If it's
not, then I think a normal distribution (approximated or exact) combined
with adjustment of the range would work best. That is what "rossum"'s
solution does if you change the "spread" parameter.

If you want the ability to tighten the clustering arbitrarily without
sacrificing the complete range, you need a different solution.
Unfortunately, while I might have been paying more attention in my stats
class than you were, it was a long time ago, and I don't have that
information off the top of my head. :)

I suspect you could apply some sort of exponential adjustment to the
basic normal distribution. That is, choosing random numbers that have
normal distribution, and then adjusting them. Maybe something like this:

int DegreeRandom(int degreeCenter, int degreeExtent, int
crandIterations, float gravity)
{
Random rand = this.Session["MyRandom"] as Random;
float unitRand = 0;

for (int i = 0; i < crandIterations; i++)
{
unitRand += rand.Next(-degreeExtent, degreeExtent);
}

unitRand = unitRand / (degreeExtent * crandIterations);

unitRand = Math.Sign(unitRand) * Math.Pow(Math.Abs(unitRand), 1
/ gravity);

return degreeCenter + unitRand * degreeExtent;
}

Where "gravity" is one, this gives you the same quasi-normal
distribution as suggested before, using the iteration count passed in.
Higher values of gravity draw the randomly-generated numbers closer to
the center.

Pete
 
K

Ken Fine

Thanks for the discussion, Peter; I will read your links in just a bit. The
code I posted was confusing, and I mentioned that in my initial message.
That initial test ( (rand1 is always going to either be >= 180 or <= 180,
so one or the other if() statements will always be true) was a clumsily
articulated way to limit the range of returned values to items that would
not be upside down: you'll notice one if is limited to 270-360, and the
second is limited to 10 -70. A boolean test would have been much clearer,
and wouldn't imply that something was intended by the specific number 360.
360 was just a useless "magic number" in this case.

I will post clearer code next time. ;)

Rossum's solution is closer to the mark, but as you notice, a bit coarse in
its control

This may be an astonishingly naive and un-Math-ey idea, but I am wondering
if you could re-purpose some of the formulae employed in various
Flash/Actionscript easing equations to help calculate different
distributions.
http://robertpenner.com/easing/easing_demo.html
http://www.robertpenner.com/easing/penner_easing_as2.zip
http://www.reflektions.com/miniml/template_permalink.asp?id=399

No idea whether this is useful, or how to repurpose AS's Math classes to
..NET eqivalents. The AS stuff is a little different in that it's used to
derive motion over time. But it would be interesting if you could derive
numeric distributions that reflected the curves of those equations, and it
would be interesting if the code above was useful in that process. I am out
of my element, here.

-KF

Peter Duniho said:
Ken said:
I would now like to know how I could write my function so that the
machine would pick semi-random numbers, but so that those numbers would
be biased toward a prespecified value. Ideally it could be parameterized
such that you could choose (for lack of a better term) a "gravity"
setting. In other words, there would be paramaterized "knob" that
indicated how willing you were to let the numbers deviate from your
prespecified center value. Low "gravity" would let the numbers float all
over the place, with only slight bias. High gravity would bias the
selection very strongly toward the center. This would be useful in all
sorts of ways.

I should have paid more attention in math class.

Yes, you should have. :)
Can someone offer a suggestion? Code follows.

The code you posted is unclear to me. Does it do something even similar
to what you want? You don't even have a way for the last statement in the
method to be executed (rand1 is always going to either be >= 180 or <=
180, so one or the other if() statements will always be true).

Anyway, for starters you may want to read these articles:

http://en.wikipedia.org/wiki/Statistical_distribution
http://en.wikipedia.org/wiki/Normal_distribution

As you may notice, the question you asked is perhaps a lot more
complicated than you might have guessed. :)

You've gotten a couple of answers so far, but it's not clear from your
original post that they are necessarily the answers you're looking for.

The first, from "mr peanut", does not produce a normal distribution (ie
"bell curve"). It will produce a linear distribution, with the range of
width "Increment" shifted relative to "Xi" according to what he calls
"gravity". You could accomplish the same simply by picking appropriate
boundaries to pass to the Random.Next() method.

The second, from "rossum", produces a quasi-normal distribution (that is,
as the number of repetitions goes up, the resulting distribution of random
numbers is increasingly closer to an actual normal distribution). However,
you don't get very much control of the "gravity" aspect. That is, one
repetition gives you linear distribution, two jumps to a triangular-shaped
distribution, and three or more starts to approximate an exact normal
distribution.

So, you can cluster the numbers more closely to the center by adding
repititions, but the returns from this method quickly diminish. The exact
normal distribution will never on its own cluster tightly to the center,
because it has a very specific shape.

Whether you use an approximate or exact generation method for normal
distribution
(http://en.wikipedia.org/wiki/Normal_distribution#Generating_values_for_normal_random_variables)
you'll run into this issue. You can address it partially by changing the
range across which the distribution is generated; the smaller the range,
the more the "gravity". But doing so necessarily excludes any possible
occurrence of the farther ranges.

For example, suppose you start with a normal distribution centered at 90
degrees, ranging from 0 to 180. You can tighten this up by decreasing the
range to be between 45 and 135, but then you will never see values less
than 45 or greater than 135.

Whether that's a problem or not isn't clear from your post. If it's not,
then I think a normal distribution (approximated or exact) combined with
adjustment of the range would work best. That is what "rossum"'s solution
does if you change the "spread" parameter.

If you want the ability to tighten the clustering arbitrarily without
sacrificing the complete range, you need a different solution.
Unfortunately, while I might have been paying more attention in my stats
class than you were, it was a long time ago, and I don't have that
information off the top of my head. :)

I suspect you could apply some sort of exponential adjustment to the basic
normal distribution. That is, choosing random numbers that have normal
distribution, and then adjusting them. Maybe something like this:

int DegreeRandom(int degreeCenter, int degreeExtent, int
crandIterations, float gravity)
{
Random rand = this.Session["MyRandom"] as Random;
float unitRand = 0;

for (int i = 0; i < crandIterations; i++)
{
unitRand += rand.Next(-degreeExtent, degreeExtent);
}

unitRand = unitRand / (degreeExtent * crandIterations);

unitRand = Math.Sign(unitRand) * Math.Pow(Math.Abs(unitRand), 1 /
gravity);

return degreeCenter + unitRand * degreeExtent;
}

Where "gravity" is one, this gives you the same quasi-normal distribution
as suggested before, using the iteration count passed in. Higher values of
gravity draw the randomly-generated numbers closer to the center.

Pete
 
G

Guest

Yes, there are finer models. Many approaches will use the form we have:
new value = Xi + modifier (or perhaps new=Xi(factor))

In my linear example modifier = (R-Y)(Increment)

Increment is a value you choose that is related to the typical amount you
want your Xi value to change each time the function executes.

More importantly (I think) to your application is Y. This is a value you can
use as a “Knob†to shift the bias on the new value. Whatever model you
choose, you should be able to identify a similar parameter.

In my mind’s eye I pictured an application where you use a virtual knob to
adjust Y.
 
B

Ben Voigt [C++ MVP]

Ken Fine said:
Hi there,

I have written a simple function that attempts to set the angle of objects
so as to place them in aesthetically appealing ways. The code follows;
there is some stupidness in it (e.g. a test for meaningless <=180 as a
boolean test). The function is designed to return values that will avoid
positioning things a) upside down and b) at "too steep" an angle.

I would now like to know how I could write my function so that the machine
would pick semi-random numbers, but so that those numbers would be biased
toward a prespecified value. Ideally it could be parameterized such that
you could choose (for lack of a better term) a "gravity" setting. In other
words, there would be paramaterized "knob" that indicated how willing you
were to let the numbers deviate from your prespecified center value. Low
"gravity" would let the numbers float all over the place, with only slight
bias. High gravity would bias the selection very strongly toward the
center. This would be useful in all sorts of ways.

Use the arctangent function (atn). 99+% of inputs are compressed very close
to a single point (180 degrees or pi radians). Multiplication by a factor
before feeding into the atn function will affect your "gravity", addition
after running atn will determine your center point.

You might find y = g / (x * (360 - x)) to be useful as well. Use y = the
return value from rand. Then:

g / y = 360 * x - x*x
x*x - 360*x + g / y = 0
(apply quadratic formula)
x = 180 +/- sqrt(180*180 - g / y)

So there ya are:

degrees = 180 +/- sqrt(180*180 - g / (1.0 + rand()))

Pick either plus or minus with equal probability to get angles both sides of
zero, minus only for just positive angles, plus only for just negative
angles (actually very near 360)
g can vary from 0 to 180*180, you get more spread with bigger g.
Change the first 180 to move the center point. The angles you get will be
clustered 180 degrees away from the value you use.
I should have paid more attention in math class. Can someone offer a
suggestion? Code follows.

private int GetRandomAngle()
{
Random rand = this.Session["MyRandom"] as Random;
int rand1= rand.Next(0, 360);
if (rand1 >= 180)
{
return(rand.Next(270,360));

}
if (rand1 <=180)
{
return(rand.Next(10, 70));

}
return (rand.Next(280, 340));
}
 
B

Ben Voigt [C++ MVP]

Ben Voigt said:
Use the arctangent function (atn). 99+% of inputs are compressed very
close to a single point (180 degrees or pi radians). Multiplication by a
factor before feeding into the atn function will affect your "gravity",
addition after running atn will determine your center point.

You might find y = g / (x * (360 - x)) to be useful as well. Use y = the
return value from rand. Then:

g / y = 360 * x - x*x
x*x - 360*x + g / y = 0
(apply quadratic formula)
x = 180 +/- sqrt(180*180 - g / y)

So there ya are:

degrees = 180 +/- sqrt(180*180 - g / (1.0 + rand()))

Pick either plus or minus with equal probability to get angles both sides
of zero, minus only for just positive angles, plus only for just negative
angles (actually very near 360)
g can vary from 0 to 180*180, you get more spread with bigger g.
Change the first 180 to move the center point. The angles you get will be
clustered 180 degrees away from the value you use.

I think I messed that up slightly when I added the 1.0 in the denominator to
protect against negative numbers. It would still work, but you're going to
have a lot of clustering no matter what. Try this instead:

degrees = center + interval +/- sqrt(interval*interval*(1.0 - 1.0 / (1.0 +
spreadiness * rand())));

You'll want spreadiness to be small and non-zero, between 0.0001 or so and
maybe .01
center and interval are the angle the results group around and the maximum
spread in the results, respectively.
I should have paid more attention in math class. Can someone offer a
suggestion? Code follows.

private int GetRandomAngle()
{
Random rand = this.Session["MyRandom"] as Random;
int rand1= rand.Next(0, 360);
if (rand1 >= 180)
{
return(rand.Next(270,360));

}
if (rand1 <=180)
{
return(rand.Next(10, 70));

}
return (rand.Next(280, 340));
}
 
P

Peter Duniho

Semi-minor correction:

Peter said:
[...]
unitRand = Math.Sign(unitRand) * Math.Pow(Math.Abs(unitRand), 1
/ gravity);

That should read "Math.Abs(1 - unitRand)" instead of
"Math.Abs(unitRand)". Sorry!
 
R

Rick Lones

Ken said:
Hi there,

I have written a simple function that attempts to set the angle of
objects so as to place them in aesthetically appealing ways. The code
follows; there is some stupidness in it (e.g. a test for meaningless
<=180 as a boolean test). The function is designed to return values that
will avoid positioning things a) upside down and b) at "too steep" an
angle.

I would now like to know how I could write my function so that the
machine would pick semi-random numbers, but so that those numbers would
be biased toward a prespecified value. Ideally it could be parameterized
such that you could choose (for lack of a better term) a "gravity"
setting. In other words, there would be paramaterized "knob" that
indicated how willing you were to let the numbers deviate from your
prespecified center value. Low "gravity" would let the numbers float all
over the place, with only slight bias. High gravity would bias the
selection very strongly toward the center. This would be useful in all
sorts of ways.

I should have paid more attention in math class. Can someone offer a
suggestion? Code follows.

private int GetRandomAngle()
{
Random rand = this.Session["MyRandom"] as Random;
int rand1= rand.Next(0, 360);
if (rand1 >= 180)
{
return(rand.Next(270,360));

}
if (rand1 <=180)
{
return(rand.Next(10, 70));

}
return (rand.Next(280, 340));
}

In "The Art Of Computer Programming" (Volume 2), Knuth gives a couple of
algorithms for generating numbers normally disributed (on the usual bell-shaped
curve) between 0 and 1. Once you have those I believe it is not too difficult
(see any decent statistics textbook) to transform them into numbers normally
distributed around a given mean and having a given standard distribution. This
sounds close to what you are looking for.

Or, you could look up "Normal Distribution" in Wikipedia - good information
there as well, wrapped in somewhat less intimidating math . . .

HTH,
-rick-
 
K

Ken Fine

Thanks to peanut, Rossum, Peter, Ben, and Rick for a really interesting
discussion. (Who says USENET is dead?) I appreciate the pointers and input
from everyone!

-KF


Rick Lones said:
Ken said:
Hi there,

I have written a simple function that attempts to set the angle of
objects so as to place them in aesthetically appealing ways. The code
follows; there is some stupidness in it (e.g. a test for meaningless
<=180 as a boolean test). The function is designed to return values that
will avoid positioning things a) upside down and b) at "too steep" an
angle.

I would now like to know how I could write my function so that the
machine would pick semi-random numbers, but so that those numbers would
be biased toward a prespecified value. Ideally it could be parameterized
such that you could choose (for lack of a better term) a "gravity"
setting. In other words, there would be paramaterized "knob" that
indicated how willing you were to let the numbers deviate from your
prespecified center value. Low "gravity" would let the numbers float all
over the place, with only slight bias. High gravity would bias the
selection very strongly toward the center. This would be useful in all
sorts of ways.

I should have paid more attention in math class. Can someone offer a
suggestion? Code follows.

private int GetRandomAngle()
{
Random rand = this.Session["MyRandom"] as Random;
int rand1= rand.Next(0, 360);
if (rand1 >= 180)
{
return(rand.Next(270,360));

}
if (rand1 <=180)
{
return(rand.Next(10, 70));

}
return (rand.Next(280, 340));
}

In "The Art Of Computer Programming" (Volume 2), Knuth gives a couple of
algorithms for generating numbers normally disributed (on the usual
bell-shaped curve) between 0 and 1. Once you have those I believe it is
not too difficult (see any decent statistics textbook) to transform them
into numbers normally distributed around a given mean and having a given
standard distribution. This sounds close to what you are looking for.

Or, you could look up "Normal Distribution" in Wikipedia - good
information there as well, wrapped in somewhat less intimidating math . .
.

HTH,
-rick-
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top