Im looking for help with my code. Im doing app, that will be downloading random images from Imgur.com, and I've stuck on their names generator.
This is the code, that I have
char letter;
unsigned short int asciiCode = 0;
std::string imageName = "";
std::ofstream fileToStoreImageNames;
if (!fileToStoreImageNames.is_open())
return -1;
for (auto i = 0; i < 6; i++)
{
/* if getTrueOrFalse()==0 return capitalLetter() if not return smallLetter() */
asciiCode = random.getTrueOrFalse() == 0 ? random.upperCase() : random.lowerCase();
letter = static_cast <char>(asciiCode);
if (imageName.size() > 0)
imageName += letter;
else
imageName = letter;
}
fileToStoreImageNames << imageName << std::endl;
I made some generators, that are returning numbers from defined range(in case of random.upperCase() it is range of 65 to 90), there is 50% chance for upperCase and 50% for lowerCase. Later im converting those numbers by static_cast to char.
For now Im only writing those names to file, and I can see it isnt working as intended. If i just compile this code, It is writing to file something like
bbbbbb
rrrrrr
YYYYYY
vvvvvv
UUUUUU
EEEEEE
rrrrrr
but, when I debug it step by step, it is working as it should be and I get random letters. There is my file after 11 attempts, lines 8 and 11, are result of step by step debugging.
Your program seems to be too fast. If you debug your code time passes and you Random Number Generator (RNG) gets a different time point from your OS. RNGs use the current time to deliver pseudo random numbers.
You can use RNGs from the c++11 standard pseudo random number generation. The RNG object is instanciated once and will provide a different random number in every cycle of the loop.
Instead of seeding your RNGs on every call to the random functions, do it once in the constructor of that class, then store and reuse the generator all over the class member functions. Your problem occurs because if they get seeded with the same timestamp they produce the same results, thus you get the same characters calling the function multiple times within the same second. When using C++11 random library you shouldn't even use a timestamp as seed.
Related
I am C++ student and I am working on creating a random number generator.
Infact I should say my algorithm selects a number within a defined range.
I am writing this just because of my curiosity.
I am not challenging existing library functions.
I always use library functions when writing applications based on randomness but I am again stating that I just want to make it because of my curiosity.
I would also like to know if there is something wrong with my algorithm or with my approach.
Because i googled how PRNGs work and on some sites they said that a mathematical algorithm is there and a predefined series of numbers and a seed just sets the pointer in a different point in the series and after some intervals the sequence repeats itself.
My algorithm just starts moving to and fro in the array of possible values and the seed breaks the loop with different values each time. I don't i this approach is wrong. I got answers suggesting a different algorithm but they didn't explain What's wrong with my current algorithm?
Yes,there was a problem with my seed as it was not precise and made results little predictable as here:-
cout<
<
rn(50,100);
The results in running four times are 74,93,56,79.
See the pattern of "increasing order".
And for large ranges patterns could be seen easily.I got an answer on getting good seeds but that too recommended a new algorithm(but didn't say why?).
An alternative way could be to shuffle my array randomly generating a new sequence every time.And the pattern of increasing order will go off.Any help with that rearranging too will also be good.Here is the code below.And if my function is not possible please notify me.
Thanking you in anticipation.
int rn(int lowerlt, int upperlt)
{
/* Over short ranges, results are satisfactory.
* I want to make it effective for big ranges.
*/
const int size = upperlt - lowerlt; // Constant size of the integer array.
int ar[size]; // Array to store all possible values within defined range.
int i, x, ret; // Variables to control loops and return value.
long pointer = 0; //pointer variable. The one which breaks the main loop.
// Loop to initialize the array with possible values..
for (i=0, x=lowerlt; x <= upperlt; i++, x++)
ar[i]=x;
long seed = time(0);
//Main loop . To find the random number.
for (i=0; pointer <= seed; i++, pointer++)
{
ret = ar[i];
if (i == size-1)
{
// Reverse loop.
for (; i >= 0; i--)
{
ret=ar[i];
}
}
}
return ret;
}
Caveat: From your post, aside from your random generator algorithm, one of your problems is getting a good seed value, so I'll address that part of it.
You could use /dev/random to get a seed value. That would be a great place to start [and would be sufficient on its own], but might be considered "cheating" from some perspective.
So, here are some other sources of "entropy":
Use a higher resolution time of day clock source: gettimeofday or clock_gettime(CLOCK_REALTIME,...) call it "cur_time". Use only the microsecond or nanosecond portion respectively, call it "cur_nano". Note that cur_nano is usually pretty random all by itself.
Do a getpid(2). This has a few unpredictable bits because between invocations other programs are starting and we don't know how many.
Create a new temp file and get the file's inode number [then delete it]. This varies slowly over time. It may be the same on each invocation [or not]
Get the high resolution value for the system's time of day clock when the system was booted, call it "sysboot".
Get the high resolution value for the start time of your "session": When your program's parent shell was started, call it "shell_start".
If you were using Linux, you could compute a checksum of /proc/interrupts as that's always changing. For other systems, get some hash of the number of interrupts of various types [should be available from some type of syscall].
Now, create some hash of all of the above (e.g.):
dev_random * cur_nano * (cur_time - sysboot) * (cur_time - shell_start) *
getpid * inode_number * interrupt_count
That's a simple equation. You could enhance it with some XOR and/or sum operations. Experiment until you get one that works for you.
Note: This only gives you the seed value for your PRNG. You'll have to create your PRNG from something else (e.g. earl's linear algorithm)
unsigned int Random::next() {
s = (1664525 * s + 1013904223);
return s;
}
's' is growing with every call of that function.
Correct is
unsigned int Random::next() {
s = (1664525 * s + 1013904223) % xxxxxx;
return s;
}
Maybe use this function
long long Factor = 279470273LL, Divisor = 4294967291LL;
long long seed;
next()
{
seed = (seed * Factor) % Divisor;
}
The situation
Hey guys, so I'm working on a project right now. Basically I need to make a traditional slot machine, or fruit machine, or "one-armed bandit". It's a 3 x 1 x 3 character grid that changes whenever the user "pulls the lever"
I've done all of the code by myself from the top of my head as of right now, but I'm at an impasse and I wondered if you guys could possibly help.
I use the word "chamber", but think of that as being the word "Wheel" and only three of the values on the wheel are ever shown on the screen at any given time, so I called these "Blocks".
I'm trying to have a single chamber display output such as:
2
3
4
where I generated the random number of 3, and outputted 4 and 2 because they are adjacent on the chamber. This would be the start position of the chamber, which I can then manipulate.
Obviously, to get the random number converted and displayed on screen, I need to convert that integer to a char* which I'll need in the future for icons, which isn't great as I need to make a constant char.
I have two issues.
1) The first is, I call my spinChamer() method 3 times (because I have 3 chambers) but the random number generator in the method don't seem to make any difference to the output of the method, almost like there is a constant somewhere.
srand(time(NULL));
//generate start position for central block. use this to find upper and lower block.
int startpoint = rand() % 7 + 1;
2) The second is, to draw a string to a co-ordinate on the screen I have to convert to a char*. This involves converting my random int variable to a char* variable, which seems easy, however, when I try to add this converted value to the vector alongside it's upper and lower elements on the wheel, all 3 positions are the same value, when they shouldn't be, again, it seems like there is a constant somewhere that I'm missing.
for (int i = 0; i < 3; i++){
convert = std::to_string(startpoint + assigner);
temporarystore = (char*)convert.c_str();
blocks.push_back(temporarystore);
assigner++;
}
//spin around twice for visual effect.
for (int counter = 0; counter < 2; counter++){
Draw_String(drawY, drawX - 1, blocks.at(0));
Draw_String(drawY, drawX, blocks.at(1));
Draw_String(drawY, drawX + 1, blocks.at(2));
}
Any help would be greatly appreciated.
Note:
Draw_String() just draws the string to the screen, I won't edit that method due to dependencies elsewhere.
First issue: do not call srand(time(NULL)); inside the function that generates random numbers. Move it outside the function! srand() must be called only once during your program execution.
Second issue: It's not clear what you are trying to accomplish and why.
If you can use C++11 in your program, there is a new bunch of functions related to randomness.
#include <random>
#include <iostream>
namespace
{
std::random_device rd;
std::mt19937 mt(rd()); // seed the random number generator once
}
int GetRandomNumber(const int lowBound, const int highBound)
{
std::uniform_int_distribution<int> dist(lowBound, highBound);
return dist(mt);
}
int main()
{
const auto diceResult = GetRandomNumber(1, 6);
std::cout << diceResult << std::endl;
return 0;
}
I've been ripping my hair out for a while now with these random numbers in C++.
In Python, I had the awesome:
random.uniform(0, 1)
Which churned out a new random number each time I called it.
C++ has to have something like this. I Googled for a long time, and found erand48(), which I plan to implement into my raytracer (I'm translating it from Python to C++).
I tried a simple test case, but I was hoping to create a random_uniform() function which always spits out a new random number (using time() isn't going to work AFAICT, as this will be running really quickly)
unsigned short Xi[3] = {0, 1, 27};
std::cout << erand48(Xi);
And the output was (and will be every time I call the program):
0.174529
I tried using the previous output as the new Xi, like this (Xis initial value was defined):
float random_uniform() {
long generated = erand48(Xi);
int temp = generated * 1000000;
unsigned short Xi[3] = {temp - 16, temp - 7, temp - 18};
return generated;
}
But that doesn't seem like it would generate random enough numbers (and it only spits out 0. I', not sure why...).
Is there any way that I could make a function which spits out a new random number each time?
Not being familiar with python, I'm going to assume that random.uniform(0, 1) spits out a random number from a uniform distribution between 0 and 1?
If so, try the following:
srand(time(NULL));
float myRand = ((float) rand( )) / RAND_MAX;
Note that your mileage may vary though - rand() is not guaranteed to be a very high quality random number source. You may get visual artifacts depending on the implementation and how you're using it. I use a Mersenne Twister random number generator in my raytracer.
EDIT: Just to be a little clearer, that's:
...
void init_program ( )
{
...
srand(time(NULL));
...
}
...
float random_uniform ( )
{
return ((float) rand( )) / RAND_MAX;
}
...
If you call both srand and rand at the same time, you're likely to get the same "random" number each time, because unless the time has changed in the meantime you'll seed the generator with exactly the same seed, and hence get exactly the same first random number.
Is there a reason you're not just using rand(), which is part of the C++ standard library? The function you refer to is part of the Single UNIX Specification, but is probably not portable...
The reason you're getting the same value over and over is because you're not seeding the random number generator, so it behaves deterministically. Use srand() or srand48() if you're OK with the UNIX-specific functions and need the 48-bit precision. Only call it once at the beginning of your program, and pass it time(NULL). Don't worry about using time(), since you're only calling this function once, you don't need to worry about always getting the same time value.
You may also want to refer to this page about how to take the return value from rand() and scale it to the range you want effectively:
USING THE C OR C++ rand() FUNCTION
EDIT: Go back and read the docs for erand48 again. You'll notice it returns a double in the range [0, 1). You're putting that in a long, which is probably why you're always seeing zero (the value is truncated to an integer). I also think that it's probably updating the values of the unsigned long array for you with the current number in the sequence -- you provide the storage, it uses it to "keep track" of the sequence.
Try:
unsigned short xsubi[3] = { 0, 1, 27 };
for (int i = 0; i < 10; ++i)
{
double value = erand48(xsubi);
printf("%f\n", value);
}
Yeah- it's called std::rand(), comes as Standard and ships in <cstdlib>.
http://msdn.microsoft.com/en-us/library/398ax69y(v=VS.100).aspx
Might want to look into Boost.Random.
So I am in a basic High School coding class. We had to think up one
of our semester projects. I chose to
base mine on ideas and applications
that arn't used in traditional code.
This brought up the idea for use of
CUDA. One of the best ways I would
know to compare speed of traditional
methods versus unconventional is
string generation and comparison. One
could demonstrate the generation and
matching speed of traditional CPU
generation with timers and output. And
then you could show the increase(or
decrease) in speed and output of GPU
Processing.
I wrote this C++ code to generate random characters that are input into
a character array and then match that
array to a predetermined string.
However like most CPU programming it
is incredibly slow comparatively to
GPU programming. I've looked over CUDA
API and could not find something that
would possibly lead me in the right
direction for what I'm looking to do.
Below is the code I have written in C++, if anyone could point me in
the direction of such things as a
random number generator that I can
convert to chars using ASCII codes,
that would be excellent.
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
int sLength = 0;
int count = 0;
int stop = 0;
int maxValue = 0;
string inString = "aB1#";
static const char alphanum[] =
"0123456789"
"!##$%^&*"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
int stringLength = sizeof(alphanum) - 1;
char genRandom()
{
return alphanum[rand() % stringLength];
}
int main()
{
cout << "Length of string to match?" << endl;
cin >> sLength;
string sMatch(sLength, ' ');
while(true)
{
for (int x = 0; x < sLength; x++)
{
sMatch[x] = genRandom();
//cout << sMatch[x];
count++;
if (count == 2147000000)
{
count == 0;
maxValue++;
}
}
if (sMatch == inString)
{
cout << "It took " << count + (maxValue*2147000000) << " randomly generated characters to match the strings." << endl;
cin >> stop;
}
//cout << endl;
}
}
If you want to implement a pseudorandom number generator using CUDA, have a look over here. If you want to generate chars from a predetermined set of characters, you can just put all possible chars into that array and create a random index (just as you are doing it right now).
But I think it might be more valuable comparison might be one that uses brute force. Therefore, you could adapt your program to try not random strings, but try one string after another in any meaningful order.
Then, on the other hand, you could implement the brute-force stuff on the GPU using CUDA. This can be tricky since you might want to stop all CUDA threads as soon as one of them finds a solution. I could imagine the brute force process using CUDA the following way: One thread tries aa as first two letters and brute-forces all following digits, the next thread tries ab as first two letters and brute-forces all following digits, the next thread tries ac as first two letters and brute-forces all following digits, and so on. All these threads run in parallel. Of course, you could vary the number of predetermined chars such that e.g. the first thread tries aaaa, the second aaab. Then, you could compare different input values.
Any way, if you have never dealt with CUDA, I recommend the vector addition sample, a very basic CUDA example, that serves very well for getting a basic understanding of what's going on with CUDA. Moreover, you should read the CUDA programming guide to make yourself familiar with CUDAs concept of a grid of thread-blocks containing a grid of threads. Once you understand this, I think it becomes clearer how CUDA organizes stuff. To be short, in CUDA, you should replace loops with a kernel, that is executed multiple times at once.
First off, I am not sure what your actual question is? Do you need a faster random number generator or one with a greater period? In that case I would recommend boost::random, the "Mersenne Twister" is generally considered state of the art. It is a little hard to get started, but boost is a great library so worth the effort.
I think the method you arer using should be fairly efficient. Be aware that it could take up to (#characters)^(length of string) draws to get to the target string (here 70^4 = 24010000). GPU should be at an advantage here since this process is a Monte Carlo simulation and trivially parallelizable.
Have you compiled the code with optimizations?
I'm doing a book exercise that says to write a program that generates psuedorandom numbers. I started off simple with.
#include "std_lib_facilities.h"
int randint()
{
int random = 0;
random = rand();
return random;
}
int main()
{
char input = 0;
cout << "Press any character and enter to generate a random number." << endl;
while (cin >> input)
cout << randint() << endl;
keep_window_open();
}
I noticed that each time the program was run, there would be the same "random" output. So I looked into random number generators and decided to try seeding by including this first in randint().
srand(5355);
Which just generated the same number over and over (I feel stupid now for implementing it.)
So I thought I'd be clever and implement the seed like this.
srand(rand());
This basically just did the same as the program did in the first place but outputted a different set of numbers (which makes sense since the first number generated by rand() is always 41.)
The only thing I could think of to make this more random is to:
Have the user input a number and set that as the seed (which would be easy to implement, but this is a last resort)
OR
Somehow have the seed be set to the computer clock or some other constantly changing number.
Am I in over my head and should I stop now? Is option 2 difficult to implement? Any other ideas?
Thanks in advance.
Option 2 isn't difficult, here you go:
srand(time(NULL));
you'll need to include stdlib.h for srand() and time.h for time().
srand() should only be used once:
int randint()
{
int random = rand();
return random;
}
int main()
{
// To get a unique sequence the random number generator should only be
// seeded once during the life of the application.
// As long as you don't try and start the application mulitple times a second
// you can use time() to get a ever changing seed point that only repeats every
// 60 or so years (assuming 32 bit clock).
srand(time(NULL));
// Comment the above line out if you need to debug with deterministic behavior.
char input = 0;
cout << "Press any character and enter to generate a random number." << endl;
while (cin >> input)
{
cout << randint() << endl;
}
keep_window_open();
}
It is common to seed the random number generator with the current time. Try:
srand(time(NULL));
The problem is that if you don't seed the generator it will seed itself with 0 (as if srand(0) were called). PRNGs are designed to generate the same sequence when seeded the same (due to the fact that PNRGs are not really random, they're deterministic algorithms and maybe a bit because it's quite useful for testing).
When you're trying to seed it with a random number using
srand(rand());
you're in effect doing:
srand(0);
x = rand(); // x will always be the same.
srand(x);
As FigBug mentioned, using the time to seed the generator is commonly used.
I think that the point of these articles is to have a go at implementing the algorithm that is in rand() not how to seed it effectively.
producing (pseudo) random numbers is non trivial and is worth investigating different techniques of generating them. I don't think that simply using rand() is what the authors had in mind.