By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,206 Members | 1,035 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,206 IT Pros & Developers. It's quick & easy.

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

P: n/a
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));
}

Aug 24 '07 #1
Share this Question
Share on Google+
9 Replies


P: n/a

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" wrote:
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));
}

Aug 24 '07 #2

P: n/a
sorry, that's gravity=R-Y
"mr peanut" wrote:
>
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" wrote:
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));
}
Aug 24 '07 #3

P: n/a
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" <mr******@discussions.microsoft.comwrote in message
news:24**********************************@microsof t.com...
sorry, that's gravity=R-Y
"mr peanut" wrote:
>>
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" wrote:
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));
}

Aug 24 '07 #4

P: n/a
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.

Aug 25 '07 #5

P: n/a

"Ken Fine" <ke*****@newsgroup.nospamwrote in message
news:eU**************@TK2MSFTNGP04.phx.gbl...
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));
}
Aug 25 '07 #6

P: n/a

"Ben Voigt [C++ MVP]" <rb*@nospam.nospamwrote in message
news:u3**************@TK2MSFTNGP06.phx.gbl...
>
"Ken Fine" <ke*****@newsgroup.nospamwrote in message
news:eU**************@TK2MSFTNGP04.phx.gbl...
>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 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));
}
Aug 25 '07 #7

P: n/a
Semi-minor correction:

Peter Duniho wrote:
[...]
unitRand = Math.Sign(unitRand) * Math.Pow(Math.Abs(unitRand), 1
/ gravity);
That should read "Math.Abs(1 - unitRand)" instead of
"Math.Abs(unitRand)". Sorry!
Aug 25 '07 #8

P: n/a
Ken Fine wrote:
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-
Aug 25 '07 #9

P: n/a
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" <Wr******@YcharterZ.netwrote in message
news:Mb**********@newsfe02.lga...
Ken Fine wrote:
>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-
Aug 26 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.