How to choose between two values in a random way? - c

I am trying to choose one of two numbers randomly: 2 or -2. Is there a way to do it? I am trying to implement an algorithm to create a maze.

You have rand() from the C standard library, which returns a pseudo-random integer in the range [0, RAND_MAX]. You can use this function and choose one of the two numbers checking if the value returned is above or below RAND_MAX/2.
First, use srand() to initialize the pseudo-random number generator with some seed. It's common to use time() to do this as it returns a different value each time.
srand(time(NULL));
int rnd = rand();
int result = (rnd > RAND_MAX/2) ? 2 : -2;
Alternatively you could use the least significant bit of the value returned by rand(), as suggested in this other answer, since half the values returned are odd and half are even:
int result = (rnd & 1) ? 2 : -2;

There are many ways to do this, my favorite is:
a + rand() % 2 * (b - a);
but it isn't clear what does it do and it doesn't contribute on efficiency either (well if you would make it into a macro/inline function and never used with variables, modern compilers should evaluate the numbers at the compile-time), so the most elegant way to do this would be to use some kind of condition, here's an example with ternary operator:
(rand() % 2)? a: b;
BTW: There are many ways to chose between 0/1, I used rand()%2 because it's most the used technique,
but if you happened to be doing this for 6502 architecture where there's no modulo/division you can do it with bitwise-and operator like this rand() & ANY_POWER_OF_TWO or like this rand() > HALF_MAX_RAND

You can use this. It uses bitwise operations to generate either 2 or -2 without branching:
-((rand() & 1) << 2) + 2
I note that you should use srand() to seed the random number generator before using it; I commonly use srand(time(NULL)).
Step-by-step:
(rand() & 1) generates a random number: either 0 or 1.
<< 2 multiplies the previous result by 4, and the - in front of -((rand() & 1) << 2) negates that, so the result is either 0 or -4.
+ 2 adds 2, so the result is either 2 or -2.
If you'd like to see a more arithmetic-like approach that may be easier to follow, here it is:
rand % 2 * -4 + 2

Related

Repeated and Predictable RNG Values in C [duplicate]

This question already has answers here:
srand() — why call it only once?
(7 answers)
Closed 4 years ago.
I'm trying to generate 10,000 random numbers in a row in C and am having trouble getting random or even randomish results using the pseudo RNG. I used modulus in a way that I think should create uniformity, which it does, but the results are equivalent to 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3 etc. when run in a loop in another function calling RNG(4).
int RNG(int n) {
int range = RAND_MAX - (RAND_MAX % n);
srand(time(NULL));
int x = rand();
while (x > range) {
x = rand();
}
return x % n;
}
Any way to get it closer to 1,3,2,0,2,3,1,0,0,3,2,0,1 etc. would be appreciated!
Thank you!
EDIT: Thanks for the responses everyone! Moved the seeding to the start of the function calling RNG and everything is dandy now!
Do not call srand every time you want to generate a number. srand initializes the pseudo-random number generator and is intended to be called just once at the start of your program, or when you want to reset the generator. By resetting it every time, you are forcing rand to generate the same numbers every time you call it within each second on the clock.
Do not use x % n to reduce the number to a desired range. Old implementations of rand are notoriously bad and have patterns in the low bits. Instead, use x / ((RAND_MAX+1u) / n).
The code int range = RAND_MAX - (RAND_MAX % n); is flawed. Suppose n is 4 and RAND_MAX is 7, meaning rand returns 0 to 7. This code sets range to 4, and then while (x > range) x = rand(); discards 5, 6, and 7, while it retains 4. There are two bugs here: The code keeps the five values 0, 1, 2, 3, and 4, which is a mismatch to (not a multiple of) the desired range of 4, and it unnecessarily discards values. If we had kept 4, 5, 6, and 7, we would have a match. You could use:
unsigned range = (RAND_MAX + 1u) - ((RAND_MAX + 1u) % n);
and:
while (x >= range) x = rand();
If you are using C++, switch to using std::uniform_int_distribution. If you are using C, check the quality of rand in your implementation or switch to another generator such as the POSIX srandom and random.
As noted elsewhere, the fix to the repeated numbers is to move the call to srand(time(NULL)) outside this function and call it only once per program at the beginning.
As for why you're getting repeated numbers: The function is being called several times per second. Each time the function executes in a given second, time(NULL) returns the same number, which this code uses to seed the random number generator.
The sequence of random numbers generated from a particular seed will always be the same. This code takes the first number from that sequence, which is always the same for one second, until time(NULL) returns a new value.

Why does this code call rand() twice to get at least N random bits?

The first problem in Programming Pearls, Chapter 12, reads:
The C library rand() function typically returns about fifteen random bits. Use that function to implement a function bigrand() to return at least 30 random bits...
and this is the solution the author gives:
int bigrand()
{
return RAND_MAX*rand() + rand(); // why add the rand() in the last
}
Why does the author add a call to rand after the multiplication?
Without the additional rand() the result would be a multiple of RAND_MAX and therefore not even vaguely random.
In fact the code you show isn't quite correct it should be
int bigrand()
{
return (RAND_MAX+1)*rand() + rand(); // why add the rand() in the last
}
RAND_MAX is almost always 2^x-1 for some x. Without the +1 there is overlap between RAND_MAX*rand() and rand() so you are effectively adding two random numbers which skews the randomness (e.g. like adding together two dice throws).
Adding the extra 1 makes it a power of 2 so RAND_MAX*rand() has the bottom x bits all 0; the additional rand() fills in the bottom bits. This is more like shifting the first rand() left and or-ing in the second.
Note that this method is OK for just generating a bit of non-critical test data but shouldn't be used if true linear randomness is required; you should be using using a true 30 bit (or more) random number generator if you need 30 bits.
The problem for which this is the solution reads:
The C library rand() function typically returns about fifteen random bits. Use that function to implement a function bigrand() to return at least 30 random bits...
A straightforward way to do that is to combine the output of 2 rand() calls, filling the necessary number of bits, 15 at a time. This
RAND_MAX * rand()
fills the most significant 15 bits, and the addition takes care of the rest.
This of course is undefined behaviour if the value of RAND_MAX makes an int type overflow (on my system, I find #define RAND_MAX 0x7fffffff). If the rand specification were a bit more strict, e.g. to say that only the lowest 15 bits are random (an unlikely and fictitious scenario), we could do:
int bigrand(void)
{
return ((rand() & 0x7fff) << 15) | (rand() & 0x7fff);
}

A line which randomizing a number between two values

my problem this time is not using a line but understanding it,
i received this line from my teacher to randomize a number between the MIN and MAX values, and it works perfectly, but i have tried to understand How exactly and i just couldn't.
I would be happy if anyone could explain it to me step by step (please not i'm not 100% sure how the rand() function works)
Thanks!
int number = (rand() % (DICE_MAX - DICE_MIN +1)) + DICE_MIN; // Randomizing a value between 'DICE_MAX' and 'DICE_MIN' which can be defined on the head of this program.
The function rand() generates a random (well, pseudo-random to be precise) number. The int returned from it has a large range, so you need to scale it to necessary range.
Assuming DICE_MIN to be 1 and DICE_MAX to be 6, you need to generate random integers in the range [1, 6]. There are 6 numbers in the range, and DICE_MAX - DICE_MIN + 1 = 6. So whatever integer you get from rand() the value of rand() % (DICE_MAX - DICE_MIN + 1) will be in the range [0, 5]. Adding the minimum of the required range DICE_MIN to it shifts the range to [1, 6].
This is a very widely practiced technique for generating random numbers in a given range.
rand:
Function: Random number generator.
Include: stdlib.h
syntax: int rand(void);
Return Value: The function rand returns the generated pseudo random number.
Description: The rand function generates an integer between 0 and RAND_MAX (a symbolic constant defined in stdlib.h). standard C states that the value of RAND_MAX must be at least 32767. If rand truly produces integers at random, every number between 0 and RAND_MAX has an equal probability of being chosen each time rand is called.
How it works?
Take an example of rolling a dice (six sided). The remainder operator % is used here in conjugation with rand as :
rand % 6;
to produce integers in the range 0 to 5. This is called scaling. The number 6 is called scaling factor. But, we need to generate number from 1 to 6. Now we shift the range of numbers produced by adding 1 to our result (1 + rand%6).
In general
n = a + rand() % b;
where a is the shifting value (which is equal to the first number in the desired range of consecutive integers, i.e, to lower bound) and b is equal to the width of the desired range of consecutive integers.
In the provided snippet of your's
int number = (rand() % (DICE_MAX - DICE_MIN +1)) + DICE_MIN;
DICE_MAX - DICE_MIN +1 is desired width and DICE_MIN is the shifting value.
Further reading: Using rand().

libc random number generator flawed?

Consider an algorithm to test the probability that a certain number is picked from a set of N unique numbers after a specific number of tries (for example, with N=2, what's the probability in Roulette (without 0) that it takes X tries for Black to win?).
The correct distribution for this is pow(1-1/N,X-1)*(1/N).
However, when I test this using the following code, there is always a deep ditch at X=31, independently from N, and independently from the seed.
Is this an intrinsic flaw that cannot be prevented due to the implementation specifics of the PRNG in use, is this a real bug, or am I overlooking something obvious?
// C
#include <sys/times.h>
#include <math.h>
#include <stdio.h>
int array[101];
void main(){
int nsamples=10000000;
double breakVal,diffVal;
int i,cnt;
// seed, but doesn't change anything
struct tms time;
srandom(times(&time));
// sample
for(i=0;i<nsamples;i++){
cnt=1;
do{
if((random()%36)==0) // break if 0 is chosen
break;
cnt++;
}while(cnt<100);
array[cnt]++;
}
// show distribution
for(i=1;i<100;i++){
breakVal=array[i]/(double)nsamples; // normalize
diffVal=breakVal-pow(1-1/36.,i-1)*1/36.; // difference to expected value
printf("%d %.12g %.12g\n",i,breakVal,diffVal);
}
}
Tested on an up-to-date Xubuntu 12.10 with libc6 package 2.15-0ubuntu20 and Intel Core i5-2500 SandyBridge, but I discovered this already a few years ago on an older Ubuntu machine.
I also tested this on Windows 7 using Unity3D/Mono (not sure which Mono version, though), and here the ditch happens at X=55 when using System.Random, while Unity's builtin Unity.Random has no visible ditch (at least not for X<100).
The distribution:
The differences:
This is due to glibc's random() function not being random enough. According to this page, for the random numbers returned by random(), we have:
oi = (oi-3 + oi-31) % 2^31
or:
oi = (oi-3 + oi-31 + 1) % 2^31.
Now take xi = oi % 36, and suppose the first equation above is the one used (this happens with a 50% chance for each number). Now if xi-31=0 and xi-3!=0, then the chance that xi=0 is less than 1/36. This is because 50% of the time oi-31 + oi-3 will be less than 2^31, and when that happens,
xi = oi % 36 = (oi-3 + oi-31) % 36 = oi-3 % 36 = xi-3,
which is nonzero. This causes the ditch you see 31 samples after a 0 sample.
What's being measured in this experiment is the interval between successful trials of a Bernoulli experiment, where success is defined as random() mod k == 0 for some k (36 in the OP). Unfortunately, it is marred by the fact that the implementation of random() means that the Bernoulli trials are not statistically independent.
We'll write rndi for the ith output of `random()' and we note that:
rndi = rndi-31 + rndi-3 with probability 0.75
rndi = rndi-31 + rndi-3 + 1 with probability 0.25
(See below for a proof outline.)
Let's suppose rndi-31 mod k == 0 and we're currently looking at rndi. Then it must be the case that rndi-3 mod k ≠ 0, because otherwise we would have counted the cycle as being length k-3.
But (most of the time) (mod k): rndi = rndi-31 + rndi-3 = rndi-3 ≠ 0.
So the current trial is not statistically independent of the previous trials, and the 31st trial after a success is much less likely to succeed than it would in an unbiased series of Bernoulli trials.
The usual advice in using linear-congruential generators, which doesn't actually apply to the random() algorithm, is to use the high-order bits instead of the low-order bits, because high-order bits are "more random" (that is, less correlated with successive values). But that won't work in this case either, because the above identities hold equally well for the function high log k bits as for the function mod k == low log k bits.
In fact, we might expect a linear-congruential generator to work better, particularly if we use the high-order bits of the output, because although the LCG is not particularly good at Monte Carlo simulations, it does not suffer from the linear feedback of random().
random algorithm, for the default case:
Let state be a vector of unsigned longs. Initialize state0...state30 using a seed, some fixed values, and a mixing algorithm. For simplicity, we can consider the state vector to be infinite, although only the last 31 values are used so it's actually implemented as a ring buffer.
To generate rndi: (Note: ⊕ is addition mod 232.)
statei = statei-31 ⊕ statei-3
rndi = (statei - (statei mod 2)) / 2
Now, note that:
(i + j) mod 2 = i mod 2 + j mod 2 if i mod 2 == 0 or j mod 2 == 0
(i + j) mod 2 = i mod 2 + j mod 2 - 2 if i mod 2 == 1 and j mod 2 == 1
If i and j are uniformly distributed, the first case will occur 75% of the time, and the second case 25%.
So, by substitution in the generation formula:
rndi = (statei-31 ⊕ statei-3 - ((statei-31 + statei-3) mod 2)) / 2
= ((statei-31 - (statei-31 mod 2)) ⊕ (statei-3 - (statei-3 mod 2))) / 2 or
= ((statei-31 - (statei-31 mod 2)) ⊕ (statei-3 - (statei-3 mod 2)) + 2) / 2
The two cases can be further reduced to:
rndi = rndi-31 ⊕ rndi-3
rndi = rndi-31 ⊕ rndi-3 + 1
As above, the first case occurs 75% of the time, assuming that rndi-31 and rndi-3 are independently drawn from a uniform distribution (which they're not, but it's a reasonable first approximation).
As others pointed out, random() is not random enough.
Using the higher bits instead of the lower ones does not help in this case. According to the manual (man 3 rand), old implementations of rand() had a problem in the lower bits. That's why random() is recommended instead. Though, the current implementation of rand() uses the same generator as random().
I tried the recommended correct use of the old rand():
if ((int)(rand()/(RAND_MAX+1.0)*36)==0)
...and got the same deep ditch at X=31
Interstingly, if I mix rand()'s numbers with another sequence, I get rid of the ditch:
unsigned x=0;
//...
x = (179*x + 79) % 997;
if(((rand()+x)%36)==0)
I am using an old Linear Congruential Generator. I chose 79, 179 and 997 at random from a primes table. This should generate a repeating sequence of length 997.
That said, this trick probably introduced some non-randomness, some footprint... The resulting mixed sequence will surely fail other statistical tests. x never takes the same value in consecutive iterations. Indeed, it takes exactly 997 iterations to repeat every value.
''[..] random numbers should not be generated with a method chosen at random. Some theory should be used." (D.E.Knuth, "The Art of Computer Programming", vol.2)
For simulations, if you want to be sure, use the Mersenne Twister

C quick calculation of next multiple of 4?

What's a fast way to round up an unsigned int to a multiple of 4?
A multiple of 4 has the two least significant bits 0, right? So I could mask them out and then do a switch statement, adding either 1,2 or 3 to the given uint.
That's not a very elegant solution..
There's also the arithmetic roundup:
myint == 0 ? 0 : ((myint+3)/4)*4
Probably there's a better way including some bit operations?
(myint + 3) & ~0x03
The addition of 3 is so that the next multiple of 4 becomes previous multiple of 4, which is produced by a modulo operation, doable by masking since the divisor is a power of 2.
I assume that what you are trying to achieve is the alignment of the input number, i.e. if the original number is already a multiple of 4, then it doesn't need to be changed. However, this is not clear from your question. Maybe you want next multiple even when the original number is already a multiple? Please, clarify.
In order to align an arbitrary non-negative number i on an arbitrary boundary n you just need to do
i = i / n * n;
But this will align it towards the negative infinity. In order to align it to the positive infinity, add n - 1 before peforming the alignment
i = (i + n - 1) / n * n;
This is already good enough for all intents and purposes. In your case it would be
i = (i + 3) / 4 * 4;
However, if you would prefer to to squeeze a few CPU clocks out of this, you might use the fact that the i / 4 * 4 can be replaced with a bit-twiddling i & ~0x3, giving you
i = (i + 3) & ~0x3;
although it wouldn't surprise me if modern compilers could figure out the latter by themselves.
If by "next multiple of 4" you mean the smallest multiple of 4 that is larger than your unsigned int value myint, then this will work:
(myint | 0x03) + 1;
(myint + 4) & 0xFFFC
If you want the next multiple of 4 strictly greater than myint, this solution will do (similar to previous posts):
(myint + 4) & ~3u
If you instead want to round up to the nearest multiple of 4 (leaving myint unchanged if it is a multiple of 4), this should work:
(0 == myint & 0x3) ? myint : ((myint + 4) & ~3u);
myint = (myint + 4) & 0xffffffc
This is assuming that by "next multiple of 4" that you are always moving upwards; i.e. 5 -> 8 and 4 -> 8.
This is branch-free, generally configurable, easy to understand (if you know about C byte strings), and it lets you avoid thinking about the bit size of myInt:
myInt += "\x00\x03\x02\x01"[myInt & 0x3];
Only downside is a possible single memory access to elsewhere (static string storage) than the stack.

Resources