I want to produce some random sequence of numbers between a range, for example 100 to 200
After a while, depending on some events, I want to produce some new sequence between the same range (100 to 200), but this time I want to exclude some numbers.
for example I don't want
[150,165,170]
.
for the next time, These excluded numbers may or may not be included in the sequence.
One possible approach could be an array of numbers like this:
int rndm[] {100,101,102,103,...};
and use the index of the array to generate a random number at a time:
random(rndm[0-99]);
but I need to use as few instruction/data structures as possible in order to achieve performance.
I am using C for this code and I use random() or randomSeed(seed) and I want to know what is the most efficient approach to handle this issue in terms of data structures should be used for the speed and memory?
Delta_G:
Keep the ones you want to exclude in an array and when you generate each random number roll through the array to check if it is there. If it is then get a different random number.
good idea!
example:
void setup()
{
Serial.begin(115200);
randomSeed(analogRead(A0));
}
void loop()
{
// create an arbitray sized array to be filled with unique values to exclude from desired array
const int arraySize = 5;
int exclusions[arraySize];
for (int i = 0; i < arraySize; i++) // fill the array with unique values...
{
int val;
do
{
val = random(100,200);
} while([&exclusions, &val](){
for (auto j : exclusions)
{
if (val == j)
{
return true;
}
}
return false;
}());
exclusions[i] = val;
}
Serial.print(F("Exclusion Array: "));
for (int i = 0; i < arraySize; i++)
{
Serial.print(exclusions[i]);
if (i < arraySize - 1)
Serial.print(F(", "));
}
Serial.println();
// create a new array of arbitrary length of unique random numbers in >>>the same<<< range as above (but not necessary)
const int listSize = 30;
int list[listSize];
for (int i = 0; i < listSize; i++) // fill the array with unique values that will exclude exclusions[]
{
int val;
do
{
val = random(100,200);
} while([&exclusions, &list, &val](){
for (auto j : list)
{
if (val == j)
{
return true;
}
for (auto k : exclusions)
{
if (val == k)
{
return true;
}
}
}
return false;
}());
list[i] = val;
}
// OPTIONAL -> lets sort the final arry to make spotting the duplicates easier:
for (int i = 0; i < listSize; i++)
{
for (int j = i + 1; j < listSize; j++)
{
if (list[j] < list[i])
{
int temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
}
// output the final array
Serial.print(F("Final Array: "));
for (int i = 0; i < listSize; i++)
{
Serial.print(list[i]);
if (i < listSize - 1)
Serial.print(F(", "));
}
Serial.println();
delay(5000);
}
Adel4:
I want to produce some random sequence of numbers between a range, for example 100 to 200
Do you mean a sequence of random numbers where the same number can appear more than once? Do you know how long a sequence you want to produce? Or did you want the sequence 100..200 (all 101 numbers from 100 to 200 inclusive) in random order?
Adel4:
After a while, depending on some events, I want to produce some new sequence between the same range (100 to 200), but this time I want to exclude some numbers.
for example I don't want
[150,165,170]
Do you know the maximum number of numbers you want to exclude?
.
Adel4:
for the next time, These excluded numbers may or may not be included in the sequence.
I don't know what you mean by "for the next time". Did you want the same sequence of randomly chosen numbers or a new sequence?
I prefer not to use dynamic memory allocation on an embedded system unless necessary. If the list of numbers to be excluded has a reasonable maximum length it is safer to allocate that list statically.
johnwasser:
If the list of numbers to be excluded has a reasonable maximum length it is safer to allocate that list statically.
sure, but it shouldn't affect (in any meaningful way) your algorithm for generating a list of random numbers in a range which at the same time is excluding a subset of excluded values. You already have to exclude values which may have been previously selected, so further de-selecting from the subset of excluded values then becomes more-or-less trivial regardless of the size of the excluded values.
johnwasser:
I prefer not to use dynamic memory allocation on an embedded system unless necessary.
adding some boundaries (in the above example) would surely help (e.g. what happens as the set of excluded numbers approaches the entire set of numbers within the range? quite catastrophic at the limit).
Adel4:
I want to produce some random sequence of numbers between a range, for example 100 to 200
After a while, depending on some events, I want to produce some new sequence between the same range (100 to 200), but this time I want to exclude some numbers.
for example I don't want
[150,165,170]
.
for the next time, These excluded numbers may or may not be included in the sequence.
For your example:
Generate a random number in the range 100 to 197.
If it is 150, change it to 198.
If it is 165, change it to 199.
If it is 170, change it to 200.
Otherwise, leave it alone.
Problem solved.
BulldogLowell:
Seems to lack a certain je ne sais quoi...
Oh yeah... ranbomness.
Did you miss the part about "Generate a random number in the range 100 to 197"?
If the OP doesn't care about repeats in the sequence and those three numbers were always the ones to be excluded then that technique would work. If different numbers were to be excluded you would need something like an array to detect and map them. If that list of excluded numbers can get very long (no reply about that yet) there might be memory limitations.
If the OP wants no repeats in the random permutation then a different method is needed.
BulldogLowell:
“Sequence” would imply, plural. Random would imply, well, random.
Well, the fact that they said "numbers between a range" implies that they are not using precise mathematical language. I take "random sequence of (the) numbers (in) a range" to possibly mean a random permutation of those numbers. The OP has not provided any answers or additional comments so I guess we may never know what they actually meant.