I'm currently working on a program that takes an array of 10000 random numbers, splits it evenly with five threads, and those five threads split further into 20 threads each evenly. The purpose is to find the ultimate minimum number from that original 10000 random number array.
I believe I'm on the right track. Upon further examination, something is wrong with my array traversal on level 1. I can only see one of the first 5 thread's 20 threads return. The information that comes back appears correct, but when I try to cout the information as it is happening, I get blank space for the return minimums of 4 of the L1 thread's L2 threads. (Sorry if that's a bit confusing.)
Would anyone be able to give me any tips on what to look out for? I will provide the code below.
Bear in mind, efficiency is not the goal of this program. Demonstrating multithreading is.
#include <sys/time.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctime>
#include <iostream>
#include <pthread.h>
#include <cstdlib>
#include <unistd.h>
/*
Macros were used to make modulation easier and to ease reading of the code
*/
#define L1_THREADS 5 //# of level 1 threads
#define L2_THREADS 20 //# of level 2 threads
//#define L1_ARRAY 5 //eventually unused
#define L2_ARRAY 2000 //size of level 2 array
using namespace std;
//structure to house the Thread Parameters required
struct ThreadParameters{
int* array;
int start;
int end;
int smallest;
};
//function to find the minimum value at the bottom level of the thread spread
void* find_min(void* args){
struct ThreadParameters* specs = (struct ThreadParameters*)args;
int *array = specs->array;
int start = specs->start;
int end = specs->end;
int smallest = array[start];
for(int i = start; i < end; i++){
if(array[i] < smallest){
smallest = array[i];
}
}
specs->smallest = smallest;
return NULL;
}
//function to find the minimum value of the values returned by the threads it creates
void* find_first(void* args){
pthread_t threads2[L2_THREADS] = {0};
struct ThreadParameters thread2_parameters[L2_THREADS] = {0};
struct ThreadParameters* specs = (struct ThreadParameters*)args;
int *array = specs->array;
int start = specs->start;
int end = specs ->end;
int smallest = array[start];
//Level 1, creates the 20 threads for level 2
for(int i = 0; i < L2_THREADS; i++){
thread2_parameters[i].array = array;
thread2_parameters[i].start = i*(L2_ARRAY/L2_THREADS);
thread2_parameters[i].end = (i+1)*(L2_ARRAY/L2_THREADS);
pthread_create(&threads2[i], NULL, find_min, &thread2_parameters[i]);
}
for(int i = 0; i < L2_THREADS; i++){
pthread_join(threads2[i], NULL);
}
cout << "Minimums from L2 threads: ";
for(int i = start; i < L2_THREADS; i++){
cout << "[" << thread2_parameters[i].smallest << "]";
if(thread2_parameters[i].smallest < smallest){
smallest = thread2_parameters[i].smallest;
}
}
cout << endl;
specs->smallest = smallest;
return NULL;
}
int main(){
time_t t;
int n = 10000;
int randnum[n]; /* array of random numbers */
/* Initialize random number generator */
srand((unsigned) time(&t));
/* Generate random numbers */
for (int i = 0; i < n; i++) {
randnum[i] = rand()%10000 +1;
}
/* end of random number generation code */
pthread_t threads1[L1_THREADS] = {0};
struct ThreadParameters thread1_parameters[L1_THREADS] = {0};
//int min[L1_ARRAY];
int smallest;
smallest = randnum[0];
//Level 0, creates the first five threads for level 1
for(int i = 0; i < L1_THREADS; i++){
thread1_parameters[i].array = randnum;
thread1_parameters[i].start = i*(n/L1_THREADS);
thread1_parameters[i].end = (i+1)*(n/L1_THREADS);
pthread_create(&threads1[i], NULL, find_first, &thread1_parameters[i]);
}
for(int i = 0; i < L1_THREADS; i++){
pthread_join(threads1[i], NULL);
}
cout << "Minimums from L1 threads: ";
//finds the ultimate minimum after L1 threads return with their values
for(int i = 0; i < L1_THREADS; i++){
cout << "[" << thread1_parameters[i].smallest << "]";
if(thread1_parameters[i].smallest < smallest){
smallest = thread1_parameters[i].smallest;
}
}
cout << "\nThe ultimate minimum is " << smallest << endl;
return 0;
}
Related
The output I'm getting when I run this code after inputting any set of integers, and ending the loop with the sentinel number 999, is always 0x7ffd85bc43b0 and I can't figure out why. I think I'm missing some important code somewhere, but I'm not sure where? This program is also eventually supposed to be able to find the mean and median of the inputted numbers as well.
// HouseholdSize.cpp - This program uses a bubble sort to arrange up to 300 household sizes in
// descending order and then prints the mean and median household size.
// Input: Interactive.
// Output: Mean and median household size.
#include <iostream>
#include <string>
#include <algorithm>
#include <cmath>
#include <any>
#include <stdio.h>
using namespace std;
void swapping(int &a, int &b) { //swap the content of a and b
int temp;
temp = a;
a = b;
b = temp;
}
void display(int householdSizes, int size) {
for(int i = 0; i<size; i++){
}
}
void bubbleSort(int householdSizes[], int size) {
for(int i = 0; i<size; i++) {
int swaps = 0; //flag to detect any swap is there or not
for(int j = 0; j<size-i-1; j++) {
if(householdSizes[j] > householdSizes[j+1]) { //when the current item is bigger than next
swapping(householdSizes[j], householdSizes[j+1]);
swaps = true; //set swap flag
}
}
if(swaps== false)
break; // No swap in this pass, so array is sorted
}
}
int main()
{
// Declare variables.
const int SIZE = 300; // Number of household sizes
int householdSizes[SIZE]; // Array used to store 300 household sizes
int x;
int limit = SIZE;
int householdSize = 0;
int pairsToCompare;
bool switchOccurred;
int temp;
double sum = 0;
double mean = 0;
double median = 0;
// Input household size
cout << "Enter household size or 999 to quit: ";
cin >> householdSize;
// This is the work done in the fillArray() function
x = 0;
while(x < limit && householdSize != 999)
{
// Place value in array.
householdSizes[x] = householdSize;
// Calculate total of household sizes
x++; // Get ready for next input item.
cout << "Enter household size or 999 to quit: ";
cin >> householdSize;
} // End of input loop.
// Find the mean
// This is the work done in the sortArray() function
int n = sizeof(householdSizes)/sizeof(householdSizes[0]);
bubbleSort(householdSizes, n);
cout <<householdSizes;
// This is the work done in the displayArray() function
// Print the mean
// Find the median
// Print the median
return 0;
} // End of main function
An array can't be printed directly using cout << householdSizes; Since an array is convertible to a pointer, that is what is done implicitly behind the scenes. Change cout << householdSizes; to:
for(int i = 0; i < x; ++i){
std::cout << householdSizes[i] << " ";
}
P.S. Also do as #0x5453 says. He is right.
#include <stdlib.h>
#include <cstdlib>
#include <ctime>
using namespace std;
int minimum(int zahlen[])
{
int minimum;
int o = 0;
bool prüf = false;
while (true)
{
for (int p = 0; p < 20; p++)
{
if (o == zahlen[p])
{
minimum = zahlen[p];
prüf = true;
}
}
if (prüf == true)
{
break;
}
o++;
}
return minimum;
}
void main()
{
srand(clock());
int array[20];
for (int i = 0; i < 20; i++)
{
array[i] = rand();
}
//Minimum
cout << "Die kleinste Zufallszahl die erstellt wurde ist die: " << minimum(array) << endl;
system("PAUSE");
}
Hi,
I have to create a 20 numbers long random array and check for the smallest number.
I know my code is probably not the best method to use for this problem but I am just always getting 371, 374, 202 or 208 as result. Never something else.
Is there a problem I don't see?
It most likely has to do with your use of clock(). According to this, clock() does not give you the current time. It gives you the time since your program started. So everytime you run this program, it takes roughly the same time for it to call clock(), meaning that the random seed is always about the same. To get the actual current world time, use std::chrono::system_clock::now() instead.
Also, an easier way of finding the minimum is this.
int minimum(int _randomNumbers[], int _arraySize)
{
int minimum = _randomNumbers[0]; // By default, let's assume the element 0 has the smallest number.
// Note that in this loop, i starts from 1, since there's no need to compare with element 0.
for (int i = 1; i < _arraySize; ++i)
{
if (_randomNumbers[i] < minimum)
{
minimum = _randomNumbers[i];
}
}
return minimum;
}
I'm trying to pass random integers (between 0 and 11) to the Numbers[] array, but i have to make sure that all 10 of its elements are different. I've tried to pass the numbers first in the array, and then check if there are any numbers that are equal but its not working this way. Here's my code:
#include <iostream>
#include <time.h>
#include <stdlib.h>
using namespace std;
int main()
{
int Numbers[10];
srand( time(NULL) );
for (int i = 0; i < 10; i++ )
{
Numbers[i] = rand() % 12; // First, the integers are passed
to the array (They must be between 0 and 11)
cout << Numbers[i] << endl; // and printed to the screen
}
cout << endl << endl;
for (int u = 0; u < 10; u++)
{
if(Numbers[u] == Numbers[u - 1]) // If there are two equal
numbers
{
switch (Numbers[u]) // One of them is incremented (But that
causes problems as well because it can lead to another pair of equals)
{
case 11: // In case one of them is 11
Numbers[u]--;
break;
default:
Numbers[u]++;
break;
}
}
cout << Numbers[u] << endl;
}
return 0;
}
Halp!
Just use std::vector, std::iota and std::shuffle:
std::vector<int> v( 12 );
std::iota( v.begin(), v.end(), 0 ); // initialize with values 0..11
std::shuffle(v.begin(), v.end(), std::mt19937{std::random_device{}()}); // make em random
v.resize( 10 ); // remove extra elements
and you do not need to validate that all elements are unique
What I understood from your question that you are trying to read random numbers till all 10 numbers are different. Have a look on code below:
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <bitset>
using namespace std;
int main()
{
int Numbers[10] ;
srand(time(NULL));
//Keep flag with all the bits '0' initially
bitset<12> flags;
flags.reset();
// keep taking input till all bits are not '1'
int i = 0;
do
{
int in_num = rand() % 12;
// check if the bit at position "in_num" is 0
if (!flags[in_num])
{
Numbers[i++] = in_num;
flags.set(in_num);// set the bit 1
}
} while (i < 10);
for (int u = 0; u < 10; u++)
{
cout << endl << Numbers[u];
}
return 0;
}
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".
I keep getting an unhandled exception in my code and it has me stumped.
I am sure it is in the way I have my variables declared.
Basically I am attempting to create 3 arrays, M rows, N columns of random variables.
If I set my N = 1,000 and M = 10,000, not a problem.
If I then change M = 100,000 I get an Unhandled exception memory allocation error.
Can someone please help me understand why this is happening.
Parts of the code was written on VS2010. I have now moved on to VS2013, so any additional advice on the usage of newer functions would also be appreciated.
cheers,
#include <cmath>
#include <iostream>
#include <random>
#include <vector>
#include <ctime>
#include <ratio>
#include <chrono>
int main()
{
using namespace std::chrono;
steady_clock::time_point Start_Time = steady_clock::now();
unsigned int N; // Number of time Steps in a simulation
unsigned long int M; // Number of simulations (paths)
N = 1000;
M = 10000;
// Random Number generation setup
double RANDOM;
srand((unsigned int)time(NULL)); // Generator loop reset
std::default_random_engine generator(rand()); // Seed with RAND()
std::normal_distribution<double> distribution(0.0, 1.0); // Mean = 0.0, Variance = 1.0 ie Normal
std::vector<std::vector<double>> RandomVar_A(M, std::vector<double>(N)); // dw
std::vector<std::vector<double>> RandomVar_B(M, std::vector<double>(N)); // uncorrelated dz
std::vector<std::vector<double>> RandomVar_C(M, std::vector<double>(N)); // dz
// Generate random variables for dw
for (unsigned long int i = 0; i < M; i++)
{
for (unsigned int j = 0; j < N; j++)
{
RANDOM = distribution(generator);
RandomVar_A[i][j] = RANDOM;
}
}
// Generate random variables for uncorrelated dz
for (unsigned long int i = 0; i < M; i++)
{
for (unsigned int j = 0; j < N; j++)
{
RANDOM = distribution(generator);
RandomVar_B[i][j] = RANDOM;
}
}
// Generate random variables for dz
for (unsigned long int i = 0; i < M; i++)
{
for (unsigned int j = 0; j < N; j++)
{
RANDOM = distribution(generator);
RandomVar_C[i][j] = RANDOM;
}
}
steady_clock::time_point End_Time = steady_clock::now();
duration<double> time_span = duration_cast<duration<double>>(End_Time - Start_Time);
//Clear Matricies
RandomVar_A.clear();
RandomVar_B.clear();
RandomVar_C.clear();
std::cout << std::endl;
std::cout << "its done";
std::cout << std::endl << std::endl;
std::cout << "Time taken : " << time_span.count() << " Seconds" << std::endl << std::endl;
std::cout << "End Of Program" << std::endl << std::endl;
system("pause");
return 0;
}
// *************** END OF PROGRAM ***************
Three 100,000 x 1,000 arrays of doubles represents 300 million doubles. Assuming 8 byte doubles, that's around 2.3 GB of memory. Most likely your process is by default limited to 2 GB on Windows (even if you have much more RAM installed on the machine). However, there are ways to allow your process to access a larger address space: Memory Limits for Windows.
I'm experienced something similar then my 32-bit application allocates more than 2Gb memory.
Your vectors require about 2.1Gb memory, so it might be same problem.
Try to change platform of your application to x64. This may solve problem.