10

I need to randomly determine a yes or no outcome (kind of a coin flip) based on a probability that I can define (.25, .50, .75).

So for example, I want to randomly determine yes or no where yes has a 75% chance of being chosen. What are my options for this? Is there a C++ library I can use for this?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Josh Brittain
  • 2,162
  • 7
  • 31
  • 54

4 Answers4

26

You can easily implement this using the rand function:

bool TrueFalse = (rand() % 100) < 75;

The rand() % 100 will give you a random number between 0 and 100, and the probability of it being under 75 is, well, 75%. You can substitute the 75 for any probability you want.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • 3
    +1, and don't forget to `srand()` – amit Oct 14 '12 at 18:49
  • 7
    More or less equally probable...Suppose RAND_MAX is 32767; then for numbers 0..67, there is one more value available to be chosen at random than there is for 68..99. Whether this matters depends on the context. – Jonathan Leffler Oct 14 '12 at 18:52
  • @JonathanLeffler ah that's true.... let's see what we can do about that... – Luchian Grigore Oct 14 '12 at 18:53
  • @user1229962 as Jonathan pointed out, the distribution is not perfectly distributed. You'll have to take into account when the number is close to `RAND_MAX` - IMO this is negligible though. – Luchian Grigore Oct 14 '12 at 18:55
  • For my application if the probability is actually 75.01% it doesn't matter, as long as it's close. Thanks guys! – Josh Brittain Oct 14 '12 at 18:57
  • @user1229962 in that case, yes, that's fine. – Luchian Grigore Oct 14 '12 at 18:58
  • I don't see why this deserves a downvote... but okay. – Luchian Grigore Oct 14 '12 at 18:59
  • @user1229962 Please consider using the C++11 engines. – cooky451 Oct 14 '12 at 19:05
  • 1
    Use C++11 / TR1 . Easier not a broken distribution. – Cory Nelson Oct 14 '12 at 19:06
  • @Luchian Grigore it deserves a down vote because it's bad. Not only is the whole srand/rand machinery awfully ugly designed, but also there's no way here to get probabilities of 12.5 etc. – cooky451 Oct 14 '12 at 19:07
  • @cooky451 what do you mean by srand/rand awfully designed? Also... sure there is, %1000, < 125... – Luchian Grigore Oct 14 '12 at 19:08
  • 1
    @Luchian Grigore By awfully designed I mean that there is only one state for the whole application. This is so bad in so many ways, I have to wonder way anyone would even consider using that. And yes, % 1000 is a way, but what's the next step? 10000? 100000? Not good, that's most likely bigger than RAND_MAX. A real distribution is the way to go (as I already stated). – cooky451 Oct 14 '12 at 19:12
  • 1
    @cooky451 I totally agree that better options exist, but I still think this is still a valid alternative, especially for such a simple task. If I wanted a bool with 75% probability, I'd use `rand`... – Luchian Grigore Oct 14 '12 at 19:17
  • @LuchianGrigore I wouldn't. Who know where srand() gets called in a big application or which other functions use rand(). I don't want to share the state with the whole application. As for the 75%: That only where examples. He mentioned "kind of a coin flip", which implies that he will most likely need probabilities like 12.5% etc. This "algorithm" is just not suitable for the task. – cooky451 Oct 14 '12 at 19:23
  • @cooky451 also, your answer seems to only apply for C++11. – Luchian Grigore Oct 14 '12 at 19:27
  • 3
    If RAND_MAX is 32767, the percentage of selected values less than 75 will be about 75.0518% theoretically (100 * (328*68 + 327 * 7) / 32768 = 75.0518); empirically, I measured 75.0564%. If RAND_MAX is 0x7FFFFFFF, the difference is much smaller (75.0008% empirically; 100*(21474837*48 + 21474836*27) / 2147483648 = 75.00000056% theoretically). If you have the C99 minimally acceptable `rand()` function, there's a noticeable (bit still small and often insignificant) bias; if you have 32-bit RAND_MAX, the bias is usually negligible. But you must know what RAND_MAX is to make that judgement call. – Jonathan Leffler Oct 14 '12 at 19:32
9

Check at the C++11 pseudo random number library.

http://en.cppreference.com/w/cpp/numeric/random

http://en.wikipedia.org/wiki/C%2B%2B11#Extensible_random_number_facility

std::random_device rd;
std::uniform_int_distribution<int> distribution(1, 100);
std::mt19937 engine(rd()); // Mersenne twister MT19937

int value=distribution(engine);
if(value > threshold) ...

like this, then say all above 75 is true, and all below is false, or whatever threshold you want

Unlike rand you can actually control the properties of the number generation, also I don't believe rand as used in other answers (using modulo) even presents a uniform distribution, which is bad.

111111
  • 15,686
  • 6
  • 47
  • 62
  • Please use a real distribution, so I can vote you up. – cooky451 Oct 14 '12 at 18:57
  • @cooky451 surely if it is supposed to mimmic a coin toss uniform is the correct distribution? – 111111 Oct 14 '12 at 18:59
  • But you're not emulating the coin flips (that would be taking 1 out 2 several times), you're doing all at once. The next step would be a probability of 12.5, how are you going to do that with an integer? Sure, you can then switch to a [1..1000] range, but still, a real distribution is the logical way to go. – cooky451 Oct 14 '12 at 19:03
  • Actually... Yes! this is better. if using modulo you get uniform distribution just when (threshold mod 2 = 0) because C++ RAND_MAX = 2^31 - 1. Or there are 2^31 possible values. (adding zero) Example. rand() % 5 where (suposition) RAND_MAX = 16 ***** ***** ***** *[----] <--- this is 4 spaces make impossible the uniform distr. **p : probability**; p(rand() % 4 == 0) = 4/16 p(rand() % 4 == 1) = 3/16 p(rand() % 4 == 2) = 3/16 p(rand() % 4 == 3) = 3/16 p(rand() % 4 == 4) = 3/16 – Moises Rojo Dec 28 '17 at 08:35
3

std::random_device or boost::random if std::random_device is not implemented by your C++ compiler, using a boost::random you can use bernoulli_distribution to generate a random bool value!

BigBoss
  • 6,904
  • 2
  • 23
  • 38
1
#include <cstdlib>
#include <iostream>
using namespace std;

bool yesOrNo(float probabilityOfYes) {
  return rand()%100 < (probabilityOfYes * 100);
}

int main() {
    srand((unsigned)time(0)); 
    cout<<yesOrNo(0.897);
}

if you call yesOrNo(0.75) it will return true 75% of the time.

Ionut Hulub
  • 6,180
  • 5
  • 26
  • 55
  • since `probabilityOfYes` is of type `int`, it is identical to `yesOrNo(0)` and will return always `no`. (probably meant it to be a `float` or a `double`) – amit Oct 14 '12 at 18:52
  • @amit that's right. I have edited the code. – Ionut Hulub Oct 14 '12 at 18:53