2

All I need to do is generate a random integer between 0 and 3 for example. I am using this function:

void Crossover(int parents[2][3])
{
  int ranDpart;
  int ranDparent;
  for(int i=0; i<10; i++)
  {
    for(int j=0; i<3; j++)
    {
      ranDpart = random(0,3);
      ranDparent = random(0,2);
      newGen[i][j] = parents[ranDparent][ranDpart];
    }
  }
}

where as you see parents is input with size of 2x3 and newGen is 10x3 2D array. As seen here in the code, this function is supposed to randomly take one of parent and a part of this parent to make a new "child". Am I doing something wrong? I think that random gives me bad results. I tried some online compiler and random gives me numbers like "1804289383" even if I tried to make it long. Can you guys help me with random int?

4
  • Could you print the values you are getting? That will be helpful.
    – user31481
    Nov 25, 2017 at 17:00
  • In what library is that 'random' function defined? Nov 25, 2017 at 17:28
  • some online compiler ? Well, there's a part of your problem. The other part is in the code that you don't show us. Can you try a real Arduino board ?
    – Jot
    Nov 25, 2017 at 17:39
  • I didn't show you the code cause it is little bit long. And btw what do you mean about real Arduino board? I have official arduino board not that chinesse one.
    – Apuna12
    Nov 25, 2017 at 19:16

3 Answers 3

2

stdlib.h defines a few psuedo-random number functions. I am not familiar with a random function taking two arguments, presumably the low and high end of the desired range, that you've specified in your code.

For what it's worth, in plain old C use the modulo operator to achieve the range you want using stdlib's srand and rand functions:

/* seed psuedo-random number generator during setup with something */
srand(0xdeadbeef);

and in your function simply use modulus to get your range:

int ranDpart = rand() % 3; /* range: 0,1,2 */
int ranDparent = rand() % 2; /* range: 0,1 */

If your ranges should be inclusive e.g. [0,3] and [0,2] then

int ranDpart = rand() % 4; /* 0,1,2,3 */
int ranDparent = rand() % 3; /* 0,1,2 */
5
  • 3
  • this always show me only one exact number. And what I am supposed to write into srand brackets?
    – Apuna12
    Nov 25, 2017 at 19:18
  • @Apuna12. Without srand, random will always return the same sequence. To change that sequence from run to run, you give srand a different start value each time. What value? Choose one, whatever, different from others you previously used.
    – user31481
    Nov 26, 2017 at 8:58
  • yep. that helped but I have another problem. I generate random in a cycle. After several cycles it generates only zeros... Is there any way to get through this?
    – Apuna12
    Nov 26, 2017 at 13:11
  • and sometimes other numbers.. for example now it game me only 7s
    – Apuna12
    Nov 26, 2017 at 13:16
0

Unfortunatly, "real random" value don't really exist in computer. If you just call a random function many time, you'll get (in many cases) same result. For that, before calling a random generator, you have to set a "seed". The example here: https://www.arduino.cc/reference/en/language/functions/random-numbers/random/ give a solution, using:

 randomSeed(analogRead(0));

If the PIN 0 (used in this example) is not connected, you'll get some "noise" on it and this will create the seed for your random function.

5
  • this is TERRIBLE advice that leaves a false sense of security. most floating analog inputs only bounce 10-20 levels, meaning your sketch has only 10-20 outcomes. now, if you sample analog pin(s) for a short while, and add up the results, you ca get a much larger seed spread, but the advice on the arduino site is pure garbage from a cryptography perspective...
    – dandavis
    Nov 27, 2017 at 18:34
  • I agree. The question is "how to get a seed?" On Atari machine, the seed was automaticly "created" by getting position of the screen beam at moment you called random(). Maybe on Arduino wait for a user action and use the "time" of this action? Any ideas welcomed.
    – Peter
    Nov 27, 2017 at 20:13
  • read 100 values on 4 pins, summing the result in a long, feeding that long to randomSeed()
    – dandavis
    Nov 27, 2017 at 20:18
  • Use the LSBs of multiple analogRead(anypin) to form a random number - unfortunately on Arduino the analogRead() is poorly coded so you will have some auto-correlation, even with the LSB approach. It is terribly to use one analogRead(). But that's much much better than summing up multiple analogRead() - the law of large numbers dictates its limited randomness.
    – dannyf
    Nov 29, 2017 at 0:29
  • if you want to read up more on this: dannyelectronics.wordpress.com/2016/03/19/…
    – dannyf
    Nov 29, 2017 at 0:30
0

The random(a,b) function does work. If it doesn't there is something else going on. You mention the program is long. A couple of things to remember when programming Arduinos is that

  1. In C there is no boundary checking, so when an array is indexed out of range unexpected behavior or crashes occur.
  2. Arduinos have very little RAM. The UNO only has 2K. Part of that is used for the stack. When memory runs low the stack can overwrite program variables and again create unexpected results or crashes e.g. endless reboots.

There are some functions that return the amount of free RAM available at run time, use those with Serial.print() for debugging. There are some freeRam() functions here, the last one works well for me (with UNO)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.