generating random numbers for array elements - c++

I have a problem in generating binary random numbers in C++. I want to make an array and each element contain random numbers in binary form. And I want to XOR elements together. This is my code
void Msg::setXOR(double Code)
{
int array[30];
srand ( time(0) );
for(int j = 0;j<30;j++)
{
i = rand();
array[j]=i
double x = array[j]^ array[j+1]^ array[J+2];
code = x ;
this -> code_var = code
}
}
It doesn't work and it doesn't make binary random numbers. Can anyone help me how should I fix it?

std::default_random_engine generator;
std::uniform_int_distribution<int> distribution;
auto generatef = std::bind(distribution,generator);
std::array<int,30> array;
std::generate(array.begin(), array.end(), generatef);
double x = std::accumulate(array.begin(), array.end(), 0, std::bit_xor<>);

you did not store the generated random num in the array.
int array[30];
srand ( time(0) );
int x=0;
for (int j = 0;j<30;j++)
{
array[j]=rand();
x ^= array[j];
}
return x;

Related

How to fill array with random numbers in Counting Sort Algorithm in C++

#include iostream
using namespace std;
int k=0;
void sort_func(int A[],int B[],int n)
{
int count[k+1],t;
for(int i=0;i<=k;i++)
{
count[i] = 0;
}
for(int i=0;i<n;i++)
{
t = A[i];
count[t]++;
}
for(int i=1;i<=k;i++)
{
count[i] = count[i]+count[i-1];
}
for(int i=0;i<n;i++)
{
t = A[i];
B[count[t]] = t;
count[t]=count[t]-1;
}
}
int main()
{
int n;
cout<<"Enter the size of the array :";
cin>>n;
int A[n],B[n];
cout<<"Enter the array elements: ";
for(int i=0;i<n;i++)
{
cin>>A[i];
if(A[i]>k)
{
k = A[i];
}
}
sort_func(A,B,n);
for(int i=1;i<=n;i++)
{
cout<<B[i]<<" ";
}
cout<<"\n";
return 0;
}
This is the C++ code for Counting Sort Algorithm and i can not change the code to create random array without entering values one by one
edit:Yes i meant to create random values in array A by using rand() function.
You have different options for filling an array with random elements. Just to name a few:
rand() without a seed: pseudo-random number generator; and you get the same sequence of numbers every time you run the program. Demo
std::generate(A, A + n, []() { return std::rand() % 101; });
rand() with a seed: pseudo-random number generator; depending on the seed you use, you can get a new sequence of numbers every time you run the program; for example, if you use time(NULL) as seed, which returns the current time in seconds since a given date, you would get a new sequence of numbers whenever you get a new output from time. Demo
std::srand(static_cast<unsigned int>(std::time(NULL)));
std::generate(A, A + n, []() { return std::rand() % 101; });
default_random_engine with a seed from random_device, for generating random numbers, and uniform_int_distribution, for distributing those random numbers uniformly in a given range: non-deterministic number generator or, in case a non-deterministic source is not available to the implementation, a pseudo-random number generator. Demo
As #NO_NAME pointed out in one of their comments, random_device() can throw. If you use this option, you can fall back to a rand() solution if you catch an exception. Demo
using random_generator = std::function<int()>;
random_generator rg{};
try
{
std::default_random_engine random_engine{ std::random_device{}() };
std::uniform_int_distribution<int> uniform_dist{0, 100};
rg = [&uniform_dist, &random_engine]() { return uniform_dist(random_engine); };
}
catch (const std::exception& ex)
{
std::srand(static_cast<unsigned int>(std::time(NULL)));
rg = []() { return std::rand() % 101; };
}
std::generate(A, A + n, rg);
As an aside note, you could use max_element to calculate k in your code:
k = *std::max_element(A, A + n);

Algorithm crashing

int function(int A[], int n)
{
int i = 0;
int sum = 0;
int amount = 0;
while(i<n) {
if(A[i] > 0) {
sum=sum+A[i];
amount++;
}
else {
i++;
}
}
while(!(i<n)) {
if(ile>0){
return sum/amount;
} else {
return 0;
}
}
}
I am generating random array of numbers between 0-10 , Im trying to use this with this algorithm, but all the time im getting result 6422260. Can someone tell me how should I approach this?
int n;
cin >> n;
int arr[n];
srand(time(NULL));
for (int i = 0; i < 10; i++)
{
arr[i] = rand() % 10;
}
function(arr, n);
Here is a solution to your problem:
#include <random>
#include <iostream>
void fill(int arr[]);
int random(int from, int to);
using namespace std;
int main(void)
{
int arr[10];
fill(arr);
for(int i = 0; i<10; i++)
printf("%d ", arr[i]);
return 0;
}
void fill(int arr[]){
for(int i=0;i<(*(&arr + 1) - arr);i++){
arr[i] = random(0, 10);//adjust accordngly
}
}
int random(int from, int to){
std::random_device dev;
std::mt19937 rng(dev());
std::uniform_int_distribution<std::mt19937::result_type> dist6(from, to); // distribution in range [from, to]
return dist6(rng);
}
Your problem is you are not generating random numbers your algorithm is generating the same set of numbers! You need a logic to generate random number. Usually they are generated from system time ...
Attribution : https://stackoverflow.com/a/13445752/14911094
#alkantra, your problem is not generating random numbers. Basically, you are asking your question wrong. If required, it should be separated:
What's this code doing?
How to generate a random sequence?
The algorithm you are trying to achieve is for calculating arithmetic mean (or simply average). If you remember the formula for calculating arithmetic mean you learnt in school, the formula is:
arithmetic mean = sum/n
where
sum - sum of all numbers (from the given array[] of course)
n - count of the numbers in the given array[]
The purpose of the sum variable is to sum all given numbers, if not equal to 0, and n(in your code amount) just increases for every number added to sum.
And in the end the function should return, as the formula says, sum/amount. I could write this code, i.e. the whole program (except for the random()), though it's quite easy, so I'll leave it up to you.
About the random library, I don't know much, but there are may resources on the net, so take your time.
https://www.tutorialspoint.com/cplusplus-program-to-generate-random-number
https://www.tutorialspoint.com/rand-and-srand-in-c-cplusplus

C++ Generating random numbers in functions

For a project that I am working on I need to generate a vector of random numbers within a function. The problem is that I end up generating the same vector of numbers each time. I have this example that reproduces my problem:
#include <iostream>
#include <random>
std::vector<double> generate(std::default_random_engine generator, double mean, double sigma, int n)
{
std::vector<double> generated(n,0);
std::normal_distribution<double> distribution(mean,sigma);
for (int i = 0;i<n;i++)
generated[i] = distribution(generator);
return generated;
}
std::vector<double> generate(double mean, double sigma, int n)
{
std::vector<double> generated(n,0);
std::default_random_engine generator;
std::normal_distribution<double> distribution(mean,sigma);
for (int i = 0;i<n;i++)
generated[i] = distribution(generator);
return generated;
}
int main(int argc, char** argv)
{
// Read inputs
int nrolls = 20; // number of experiments
int ntimes = 50;
double mean = 100;
double sigma = 4;
bool useFunction(false);
if (argc>1)
useFunction=true;
// crates series
std::vector< std::vector<double> > results(ntimes,std::vector<double>());
std::default_random_engine generator;
for (int i = 0;i<ntimes/4;i++){
std::vector<double> generated(nrolls,0);
std::normal_distribution<double> distribution(mean,sigma);
for (int i = 0;i<nrolls;i++)
generated[i] = distribution(generator);
results[i] = generated;
}
for (int i = ntimes/4;i<ntimes/2;i++)
results[i] = generate(generator,mean,sigma,nrolls);
for (int i = ntimes/2;i<3*ntimes/4;i++){
std::vector<double> generated(nrolls,0);
std::normal_distribution<double> distribution(mean,sigma);
for (int i = 0;i<nrolls;i++)
generated[i] = distribution(generator);
results[i] = generated;
}
for (int i = 3*ntimes/4;i<ntimes;i++)
results[i] = generate(mean,sigma,nrolls);
//
// Display all random numbers
for (int i = 0;i<ntimes;i++){
std::cout<<i;
for (int j = 0;j<nrolls;j++)
std::cout<<" "<<results[i][j];
std::cout<<std::endl;
}
// Check number of equal results
int n_equal(0);
int n_total(0);
for (int i=0;i<ntimes;i++){
for (int k = 0;k<nrolls;k++){
for (int j=i+1;j<ntimes;j++){
n_total++;
if (results[i][k] == results[j][k])
n_equal++;
}
}
}
std::cout<<n_equal<<"/"<<n_total<<std::endl;
// Exit
return 0;
}
I have tried to solve it by passing the generator to the function where the array of random numbers is generated but apparently, it does not work either. Can somebody give me a hint on how should I do it to get different arrays each time i call the generate function?
Thank you very much.
You have two problems here. First
std::vector<double> generate(std::default_random_engine generator, double mean, double sigma, int n)
Takes the PRNG by value, which means it makes a copy. That means every time you call the function your going to be starting from the same sequence since you never modify the generator from the call site.
The second issue is with
std::vector<double> generate(double mean, double sigma, int n)
You recreate the same generator every time you call the function. This is not going to work as it is going to create the same sequence each time.
Typically you have two options. You can pass the PRNG to the function by reference, or you declare a static PRNG in the function so it persists between function calls.
After playing a bit with them, I found it best to use global variables for the new C++ random generators. And you should have one per random number suite, so you're (statistically almost :) 100% sure to get the distribution specified.
Pseudo-random generators are static beasts by nature, since they keep numbers generated in the last computation to generate the next.

c++ vector with random unique elements with constant sum

I have an std::vector with fixed size N = 5. I want every element of the vector to be randomly selected between two positive numbers, in particular 1 and 12. (zeros are not allowed).Each element should be unique on the vector.
How can I do this? The implementation so far allows elements to be zero and have duplicates in the vector. I want to improve in order not to allow zeros and duplicates
Code so far:
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <random>
int main() {
std::random_device rd;
std::mt19937 gen(rd());
constexpr int MAX = 20;
constexpr int LINES = 5;
int sum{};
int maxNum = 12;
int minNum = 1;
std::array<int, LINES> nums;
for (int i = 0; i < LINES; ++i) {
maxNum = std::min(maxNum, MAX - sum);
minNum = std::min(maxNum, std::max(minNum, MAX - maxNum * (LINES - i)));
std::cout << minNum << " " << maxNum << std::endl;
std::uniform_int_distribution<> dist(minNum, maxNum);
int num = dist(gen);
nums[i] = num;
sum += num;
}
std::shuffle(std::begin(nums), std::end(nums), gen);
std::copy(std::begin(nums), std::end(nums), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}
Ok, there are three requirements:
Sum should be fixed
Non-repetitive numbers
Numbers should be in the range
For requirement #1 it is better sample from distribution which already have the property - Dirichlet distribution. For simplest case where all parameters are equal to 1, it is also known as simplex sampling, producing numbers uniformly distributed on N dimensional simplex. HEre is link to the C++ code.
To satisfy second&third requirement, just use acceptance/rejection
std::linear_congruential_engine<uint64_t, 2806196910506780709ULL, 1ULL, (1ULL<<63ULL)> ugen;
float MAX = 20.0f;
Simplex s(0.0f, 20.0f);
std::vector<float> v(5, 0.0f);
std::vector<int> r(5, 0);
for( ;; ) {
s.sample(v, ugen); // sampled Dirichlet
for(int k = 0; k != v.size(); ++k) {
r[k] = 1 + int(v[k]);
}
std::sort(r.begin(), r.end());
if (*r.rbegin() > 12) // array is sorted, just check last largest element
continue;
if (std::unique(r.begin(), r.end()) == r.end()) // no duplicates, good to go
break;
}
return r;
declare a boolean that starts at false, after that do a while that whill iterate until that flag is true, inside that while you will iterate until the sum of both of them = 5, you will check if the sum = 5 with an If statement, if they are then you will change the value of the flag to true. Easy as that.
I recommend you study a bit more, since you are probably new to programming (at least thats what the question makes me think, if you aren't then there is something clearly wrong).
Also, there ya go:
If statements
While loop

Arriving at a close approximation of the probability using code

I was given a math question on probability. It goes like this:
There are 1000 lotteries and each has 1000 tickets. You decide to buy 1 ticket per lottery. What is the probability that you win at least one lottery?
I was able to do it mathematically on paper (arrived at 1 - (999/1000)^1000), but an idea of carrying out large iterations of the random experiment on my computer occurred to me. So, I typed some code — two versions of it to be exact, and both malfunction.
Code 1:
#include<iostream>
#include <stdlib.h>
using namespace std;
int main() {
int p2 = 0;
int p1 = 0;
srand(time(NULL));
for (int i = 0; i<100000; i++){
for(int j = 0; j<1000; j++){
int s = 0;
int x = rand()%1000;
int y = rand()%1000;
if(x == y)
s = 1;
p1 += s;
}
if(p1>0)
p2++;
}
cout<<"The final probability is = "<< (p2/100000);
return 0;
}
Code 2:
#include<iostream>
#include <stdlib.h>
using namespace std;
int main() {
int p2 = 0;
int p1 = 0;
for (int i = 0; i<100000; i++){
for(int j = 0; j<1000; j++){
int s = 0;
srand(time(NULL));
int x = rand()%1000;
srand(time(NULL));
int y = rand()%1000;
if(x == y)
s = 1;
p1 += s;
}
if(p1>0)
p2++;
}
cout<<"The final probability is = "<< (p2/100000);
return 0;
}
Code 3 (refered to some advanced text, but I don't understand most of it):
#include<iostream>
#include <random>
using namespace std;
int main() {
int p2 = 0;
int p1 = 0;
random_device rd;
mt19937 gen(rd());
for (int i = 0; i<100000; i++){
for(int j = 0; j<1000; j++){
uniform_int_distribution<> dis(1, 1000);
int s = 0;
int x = dis(gen);
int y = dis(gen);
if(x == y)
s = 1;
p1 += s;
}
if(p1>0)
p2++;
}
cout<<"The final probability is = "<< (p2/100000);
return 0;
}
Now, all of these codes output the same text:
The final probability is = 1
Process finished with exit code 0
It seems that the rand() function has been outputting the same value over all the 100000 iterations of the loop. I haven't been able to fix this.
I also tried using randomize() function instead of the srand() function, but it doesn't seem to work and gives weird errors like:
error: ‘randomize’ was not declared in this scope
randomize();
^
I think that randomize() has been discontinued in the later versions of C++.
I know that I am wrong on many levels. I would really appreciate if you could patiently explain me my mistakes and let me know some possible corrections.
You should reset your count (p1) at the beginning of the outer loop. Also, be aware of the final integer division p2/100000, any value of p2 < 100000 would result in 0.
Look at this modified version of your code:
#include <iostream>
#include <random>
int main()
{
const int number_of_tests = 100000;
const int lotteries = 1000;
const int tickets_per_lottery = 1000;
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> lottery(1, tickets_per_lottery);
int winning_cases = 0;
for (int i = 0; i < number_of_tests; ++i )
{
int wins = 0; // <- reset when each test start
for(int j = 0; j < lotteries; ++j )
{
int my_ticket = lottery(gen);
int winner = lottery(gen);
if( my_ticket == winner )
++wins;
}
if ( wins > 0 )
++winning_cases;
}
// use the correct type to perform these calculations
double expected = 1.0 - std::pow((lotteries - 1.0)/lotteries, lotteries);
double probability = static_cast<double>(winning_cases) / number_of_tests;
std::cout << "Expected: " << expected
<< "\nCalculated: " << probability << '\n';
return 0;
}
A tipical run would output something like:
Expected: 0.632305
Calculated: 0.63125
Only seed the pseudorandom number generator by srand once at the beginning of your program. When you seed it over and over again you reset the pseudorandom number generator to the same initial state. time has a granularity measured in seconds, by default. Odds are you are getting all 1000 iterations - or most of them - within a single second.
See this answer to someone else's question for a general description of how pseudorandom number generators work.
This means that you should be creating one instance of a PRNG in your program and seeding it one time. Don't do either of those tasks inside loops, or inside functions that get called multiple times, unless you really know what you're doing and are trying to do something sophisticated such as using correlation induction strategies such as common random numbers or antithetic variates to achieve "variance reduction".