How to generate non-negative random numbers(integer) using RNGCryptoServiceProvider C# - random

I need to generate non-negative random integers in my code. The example below generates integers;
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
// Buffer storage.
byte[] data = new byte[4];
// Ten iterations.
for (int i = 0; i < 10; i++)
{
// Fill buffer.
rng.GetBytes(data);
// Convert to int 32.
int value = BitConverter.ToInt32(data, 0);
Console.WriteLine(value);
}
}
Ref: http://www.dotnetperls.com/rngcryptoserviceprovider
But it gives both positive and negative values. How do I generate only non-negative random integers?
I was earlier using Random.Next() which was giving me positive integers.

In your specific case, just use ToUInt32 in place of ToInt32
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
// Buffer storage.
byte[] data = new byte[4];
// Ten iterations.
for (int i = 0; i < 10; i++)
{
// Fill buffer.
rng.GetBytes(data);
// Convert to int 32.
int value = BitConverter.ToUInt32(data, 0);
Console.WriteLine(value);
}
}

Pseudocode:
repeat
temp <- RNG.nextInteger();
until temp >= 0;
return temp;

Related

Why won't my random selection without replacement algorithm work?

I have made a very simple algorithm that picks a set of numToPick random numbers from the range 0 to batchMax, without replacement. Then it places each selected number in an array called numsPicked. For some reason I cannot explain, it isn't working on DartPad.
import 'dart:math';
void main() {
print(randNoReplace(2, 9));
}
List<int> randNoReplace(int numToPick, int batchMax) {
List<int> numsPicked = List(numToPick);
List<int> tmpArray = List(batchMax);
//this for loop creates the tmpArray from 0 to batchMax.
for (int i = 0; i <= batchMax; i++) {
tmpArray[i] = i;
}
//this for loop randomly scrambles said tmpArray.
for (int i = 0; i <= batchMax; i++) {
int randIndex = Random().nextInt(batchMax);
int tmp = tmpArray[i];
tmpArray[i] = tmpArray[randIndex];
tmpArray[randIndex] = tmp;
}
//finally, this for loop adds the first numToPick entries of the scrambled tmpArray and adds them to numsPicked.
for (int i = 0; i < numToPick; i++) {
numsPicked[i] = tmpArray[i];
}
return numsPicked;
}
So, for example, with 2 and 9 respectively, this algorithm should theoretically give me 2 random non-duplicate numbers in the range [0, 9].
I think the main issue in your code is that your first two for-loops are going from 0 to
batchMax including batchMax. This is a problem since you are using batchMax to specify the size of your tmpArray. Since the index of a List starts at 0, we cannot ask for the batchMax-element but at most batchMax - 1.
So you code should properly be (or `tmpArray should be one element bigger):
import 'dart:math';
void main() {
print(randNoReplace(2, 9));
}
List<int> randNoReplace(int numToPick, int batchMax) {
List<int> numsPicked = List(numToPick);
List<int> tmpArray = List(batchMax);
//this for loop creates the tmpArray from 0 to batchMax.
for (int i = 0; i < batchMax; i++) {
tmpArray[i] = i;
}
//this for loop randomly scrambles said tmpArray.
for (int i = 0; i < batchMax; i++) {
int randIndex = Random().nextInt(batchMax);
int tmp = tmpArray[i];
tmpArray[i] = tmpArray[randIndex];
tmpArray[randIndex] = tmp;
}
//finally, this for loop adds the first numToPick entries of the scrambled tmpArray and adds them to numsPicked.
for (int i = 0; i < numToPick; i++) {
numsPicked[i] = tmpArray[i];
}
return numsPicked;
}
Some other minor comments:
You should properly not initialize a new Random() object each time you need a random number. Instead, you should create one instance and reuse it.
Your code are not making much use of the Dart SDK. In fact, your code could properly be simplified into:
void main() {
print(randNoReplace(2, 9));
}
List<int> randNoReplace(int numToPick, int batchMax) =>
(List.generate(batchMax, (index) => index)..shuffle())
.sublist(0, numToPick);

I think I've found a good sorting algorithm. Seems to be faster than quickSort?

This works without comparing.
First, it finds the largest number in the array and saves it in a variable called "max". Then it creates a temporary array with the length of max + 1. After that, each "tempArray[i]" counts how often a number equal to "i" has been counted in the input array. In the end, it converts "tempArray" and writes it into the input array. See for yourself.
static int[] nSort(int[] array) {
int max = array[0];
for(int i = 1; i < array.length; i++) {
max = Math.max(max, array[i]);
}
Integer[] tempArray = new Integer[max+1];
for(int i = 0; i < array.length; i++) {
if(tempArray[array[i]] == null) {
tempArray[array[i]] = 0;
}
tempArray[array[i]]++;
}
for(int[] i = new int[2]; i[0] < max + 1; i[0]++) {
if(tempArray[i[0]] != null) {
while(tempArray[i[0]] > 0) {
array[i[1]] = i[0];
i[1]++;
tempArray[i[0]]--;
}
}
}
return array;
}
I've charted the measured runtime in a graph below. Green being my algorithm red and red being quicksort.
I've used this quicksort GitHub implementation and measured runtime in the same way as implemented there.
Runtime graph:

Generate unique random numbers in Dart

How can I generate two different random numbers in dart?
I have generated two random numbers using code below.
int rand1 = Random().nextInt(16);
int rand2 = Random().nextInt(16);
if(rand1 == rand2)
// generate new random
How do I generate new random numbers until rand1 != rand2?
If you need to have two different random numbers in a fixed range, then the simplest approach would be:
var random = Random();
var n1 = random.nextInt(16);
var n2 = random.nextInt(15);
if (n2 >= n1) n2 += 1;
This ensures that the first number can assume all 16 values, and the second number can assume any of the remaining 15 values, and with as even a distribution as the random generator allows.
For two ordered distinct numbers in the range 0..15, there are 16 * 15 possible outcomes, and you probably want each outcome to be equally probable.
This code achieves this by picking the first number at random, and then picking the second number to be one of the numbers different from the first by ensuring that it is in either the range [0 .. (n1 - 1)] or the range [(n1 + 1) .. 15] ... by picking a number in the range [0 .. 14] and adding one if >= n1, shifting the range [n1 .. 14] into [(n1 + 1) .. 15].
You can do this for more numbers, but you have to do more tests and additions.
I would suggest you a different approach, looping can be pain.
// create a list say of 16 numbers.
List list = List.generate(16, (i) => i);
// shuffle it
list.shuffle();
// take the numbers now, they are always unique
int firstRandonNum = list[0];
int secondRandonNum = list[1];
This is the simplest way to do it:
import 'dart:math';
void main() {
int rand1 = Random().nextInt(16);
int rand2 = Random().nextInt(16);
while(rand1 == rand2){
rand1 = Random().nextInt(16);
rand2 = Random().nextInt(16);
}
print('$rand1 $rand2');
}
To generate any 5 unique random numbers under a range 0-49
List<int> numberList = [];
Random randomizer = new Random();
while (numberList.length < 5) {
int random_number = randomizer.nextInt(50);
if (!numberList.contains(random_number)) {
numberList.add(random_number);
}
}
A potential solution for pulling many out of many (say, 50 out of thousands) is to loop and memoize with a hash set.
I pulled this from my code, but something like:
var hashSet = HashSet();
for (var i = 0; i < boardSize; i++) {
words.add([]);
for (var j = 0; j < boardSize; j++) {
Random _random = new Random();
String wordToAdd = abstractPossibleWords[_random.nextInt(abstractPossibleWords.length)];
while (hashSet.contains(wordToAdd)) {
wordToAdd = abstractPossibleWords[_random.nextInt(abstractPossibleWords.length)];
}
words[i].add(wordToAdd);
}
}
maybe useful for you.
'max' is exclusive. the unique result number is in the return List.
List<int> getRandomNums(int countOfNum, int max) {
int num = 0;
List<int> numList = [];
var random = Random();
int i = 0;
while ( i < countOfNum) {
int oldNum = num;
num = random.nextInt(max);
if (numList.contains(num)) continue;
numList.add(num);
i++;
}
return numList;
}

How to calculate the statistical mode in Processing / Arduino

I'm a design teacher trying to help a student with a programming challenge, so I code for fun, but I'm no expert.
She needs to find the mode (most frequent value) in a dataset built using data from sensors coupled to an Arduino, and then activate some functions based on the result.
We've got most of it figured out, except how to calculate the mode in Arduino. I found the post Get the element with the highest occurrence in an array that solves the problem in JavaScript, but I haven't been able to "port" it.
I've used a HashMap to replace the js {} dynamic object instance and floats, but #weberik's port looks more straightforward.
void setup() {
int numValues = 10;
float[] values = new float[numValues]; //Create an empty sample array
for(int i = 0 ; i < numValues ; i++) values[i] = random(0.0,100.0); //Populate it with random values.
println("mode: " + mode(values));
}
float mode(float[] source) {
if (source.length == 0)
return -1;
HashMap<Float,Integer> modeMap = new HashMap<Float,Integer>();
float result = source[0];
int maxCount = 1;
for (int i = 0; i < source.length; i++) {
float el = source[i];
if (modeMap.get(el) == null)
modeMap.put(el,1);
else
modeMap.put(el,modeMap.get(el)+1);
if (modeMap.get(el) > maxCount) {
result = el;
maxCount = modeMap.get(el);
}
}
return result;
}
You've mentioned sensor input, so I presume data will be sampled continuously, so values could be stored at a certain interval, then sent to Processing for the mode.
Just a wild guess, but isn't she looking to average/smooth out sensor readings a bit?
If so, she could cache a few values (say 10) in an array in Arduino and get the average everytime a new values is added:
int vals[10]; //Array to store caches values.
void setup() {
Serial.begin(9600);
for (int i=0 ; i < 10 ; i++)
vals[i] = 0; //Init with zeroes
}
void loop() {
delay(100);
int currentVal = average(analogRead(0));
//Serial.print(currentVal,BYTE);
Serial.println(currentVal);
}
int average(int newVal) {
int total = 0; //Used to store the addition of all currently cached values
for(int i = 9; i > 0; i--) { //Loop backwards from the one before last to 0
vals[i] = vals[i-1]; //Overwrite the prev. value with the current(shift values in array by 1)
total += vals[i]; //Add to total
}
vals[0] = newVal; //Add the newest value at the start of the array
total += vals[0]; //Add that to the total as well
return total *= .1; //Get the average (for 10 elemnts) same as total /= 10, but multiplication is faster than division.
}
I ported the code from your linked post to Processing, but it's limited to int arrays.
I hope that helps.
void setup()
{
int[] numbers = {1, 2, 3, 2, 1, 1, 1, 3, 4, 5, 2};
println(mode(numbers));
}
int mode(int[] array) {
int[] modeMap = new int [array.length];
int maxEl = array[0];
int maxCount = 1;
for (int i = 0; i < array.length; i++) {
int el = array[i];
if (modeMap[el] == 0) {
modeMap[el] = 1;
}
else {
modeMap[el]++;
}
if (modeMap[el] > maxCount) {
maxEl = el;
maxCount = modeMap[el];
}
}
return maxEl;
}

Algorithm to iterate through sample space of numbers

I hope this isn't a dupe, but it's hard to boil down the problem into keywords!
This is always something that I've wondered about. Let's say you have a black box that takes n integers as an input (where n > 1). Given that there is a bounds on the integer values, how would you go about writing an algorithm that will push the entire sample space through the black box? (bonus points if n can be specified at runtime)
My attempt when n = 2 is as follows:
int min = 0;
int max = 9;
int a = min;
int b = min;
while(a <= max && b <= max)
{
blackBox(a, b);
a++;
if(a > max)
{
a = min;
b++;
}
}
The above code is fine for two variables, but as you might guess, my algorithm gets really ugly when n approaches double-digits.
Is there a better way to do this other than nesting if statements like I have done?
I know a bad way to do it, which would be to randomly generate the values for each iteration and save the inputs of previous iterations so you don't poke the black box with the same variables twice. However, I was hoping for a more speedy method as collisions really hurt the execution time as the number of unique black box calls approaches (max - min + 1) ^ n
Why not used nested loops? Then you just add more nested loops as necessary.
Might not be overly efficent but you did indicate you need to cover the entire sample space, so you're going to have to run every possible combination of values of the input variables anway - so I doubt there's much you can do about efficency unless it's possible to only evaluate against a portion of the state space.
int min = 0;
int max = 9;
for( int a = min ; a <= max ; ++a )
for( int b = min ; b <= max ; ++b )
blackBox( a , b );
Also, I think you'll find the number of unique calls is (max - min + 1) ^ n, not the other way around.
Edit:
A different run-time version to that already suggested
Imre L seems to have hit the nail on the head for a real-time version using the same language type as your question (something C-like), but since you've tagged this as language agnostic I've decided to try something different (also, I'm learning Python at the moment so was looking for an excuse to practice).
Here's a Python real-time version, in each case x will be a n-tuple, such as [1,0,3,2]. Only thing I will say is this does not include max in the state-space (in the example below it will use 0 to 2 inclusive, not 3) so you'd have to increment max before use.
import itertools
min = 0
max = 3
n = 4
for x in itertools.product(range(min,max), repeat=n):
blackBox( x )
The numbers will be held in array a that will be set dynamically eg: int a[] = new int[n]
If the blackBox cannot be modified to take a sample as array then you can either write an ugly wrapper function for calling it with different count of parameters or you are pretty much out of luck for doing it dynamically.
(Procedural) Pseudo code:
int min = 0;
int max = 9;
int a[] = array();
int count = length(a);
setToMinValue(a);
while(a[count-1] <= max)
{
blackBox(a); // or bb(a[0],a[1],...)
a[0]++;
//while next number needs to be increased
for (int i = 0; a[i] > max && i < count-1; i++) {
a[i] = min;
a[i+1]++;
}
}
Here is a generic solution, in Java:
public class Counter implements Iterator<int[]> {
private int[] max;
private int[] vector;
public Counter(int[] maxValues) {
this.max = maxValues;
this.vector = new int[maxValues.length];
}
public int[] next() {
if (!hasNext())
throw new NoSuchElementException();
int[] res = vector.clone();
int i = 0;
while (i < vector.length && vector[i] == max[i]) {
vector[i] = 0;
i++;
}
if (i == vector.length)
vector = null;
else
vector[i]++;
return res;
}
#Override
public boolean hasNext() {
return (vector != null);
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
public static void main(String[] args) {
Counter c = new Counter(new int[]{3});
while (c.hasNext()) {
System.out.println(Arrays.toString(c.next()));
}
}
}
The constructor receives the maximum values for each position. The minimum is always 0 (therefore you can use it to simulate a counter in any radix, and in any "mixed radix"). I added a usage example at the bottom.
You may think of each input to the black box as an n-digit number in a max - min + 1 radix system. For example, if min = 3 and max = 12, then max - min + 1 == 10 and each input to the black box corresponds to an n-digit number in the decimal system. Simply iterate over all the numbers from 0 to (max - min + 1)^n, decode each number and feed the resulting vector to the black box.
Here's a Java implementation:
public static interface BlackBox {
void consume(int... vector);
}
public static void iterateSample(int min, int max, int n, BlackBox bb) {
int radix = max - min + 1;
long limit = (long) Math.pow(radix, n); /* Imprecise for larger numbers! */
for (int i = 0; i < limit; i++) {
int encoded = i;
int[] decoded = new int[n];
for (int j = 0; j < n; j++) {
decoded[j] = min + (encoded % radix);
encoded /= radix;
}
bb.consume(decoded);
}
}

Resources