I'm having trouble generating two independent random sequences using the rand and srand functions. The details are below, any help would be most appreciated.
I'm working on a puzzle game for the iPhone, and usually for the random number generation I use the arc4 function. However for the multiplayer mode I want both players to have the same pieces throughout the game, and the only way I can control it is to have two repeatable random sequences. If I then send the seeds to the other device, the games will be identical. However when I use rand and srand and try to switch to the other seed, the sequence starts from scratch, I somehow have to initialize two independent sequences generated with a seed.
Thank you for your responses
Cryptographically bad PRNGs like rand() operate by feeding the previous result back into a certain mathematical procedure.
In order to continue a sequence from where it left off, all you have to do is store the last-generated number and use it as the seed:
srand(time(0));
int player1_rand_num = rand();
NSLog(#"Player 1: %d, %d, %d", rand(), rand(), rand());
srand(7);
int player2_rand_num = rand();
NSLog(#"Player 2: %d, %d, %d", rand(), rand(), rand());
// Re-seed Player 1 sequence
srand(player1_rand_num);
// Displays the same "random" numbers as the first NSLog
NSLog(#"Player 1 again: %ld, %ld, %ld", rand(), rand(), rand());
// and so on...
The random() function generates better random numbers, and has a separate pair of functions, initstate() and setstate() which will give you the state of the generator. You can store the state and pass it into setstate() to resume the sequence from where you left off. I direct you to man 3 random for the details.
First off, as others have pointed out already, you should use random() instead of rand(). Secondly, while your singleton approach may work for you, you could solve your problem more easily and IMHO more elgantly by using setstate(3). See Use of setstate(3) doesn't produce expected sequence of random numbers for an example on how to switch between two random number states.
Thank you for the suggestions, this is how I implemented the whole thing. I created a singleton class with 2 instance variables - seed1 and seed2 - anytime I want to get a number from the first generator I use the method generator1, same for generator2 method. The seed1/2 is instantly set to a newly generated number every time so I can just continue where I left off. In conlusion, Josh Caswell gave me all the information I needed. Check out the code if you ever need something like this. The object inits with seeds 1 and 1 but during the game they get replaced with some other numbers that both devices share.
#implementation RandomNumberGenerator
#synthesize seed1,seed2;
static RandomNumberGenerator *sharedGenerator = nil;
+(RandomNumberGenerator *) sharedInstance
{
if(!sharedGenerator) {
sharedGenerator = [[RandomNumberGenerator alloc] initWithSeed1:1 andSeed2:1];
}
return sharedGenerator;
}
-(id) initWithSeed1:(int) seedOne andSeed2:(int) seedTwo{
self = [super init];
if (self)
{
seed1 = seedOne;
seed2 = seedTwo;
}
return self;
}
-(int) generator1{
srand(seed1);
int j = rand();
seed1 = j;
return abs(j);
}
-(int) generator2 {
srand(seed2);
int k = rand();
seed2 = k;
return abs(k);
}
-(int) giveRandom {
//return abs(arc4random());
return abs(arc4random());
}
#end
Did you seed your random number generator?
srand( myIdenticalSeedValueForBothPartners );
See this question or here [C++ reference].
In case you don't need to call rand() many thousand times:
int nthRandBasedOnSeed( int seed, int count ) {
srand( seed );
int result;
while( 0 < count-- ) {
result = rand();
}
return result;
}
Alternately, you might consider sending with the seed a "count". This count would simply indicate where in the seeded-series you are and would get incretented each time you generate a random number with that seed. This approach gives you the flexibility of using any random generator you like and keeps communication to a minimum.
int playerSeed = 12345;
int playerRndCount = 0;
int generateRandomNumber() {
playerRndCount++;
return rand();
}
void synchSeed(seed, count) {
srand(seed);
for (int i=0; i<count; i++)
generateRandumNumber();
}
Some random number generator libraries allow you to save the state of the generator. This way, you can restore it later, and continue with a sequence already in progress. One I know of is called RandomLib, and it can be found on SourceForge.
Another option is save the seed, and count how many times you've pulled a value from the generator after seeding. Later on when you want to continue, reseed with the original seed, and pull off the same quantity. This probably isn't the best method, but should work fine if not done a lot.
Related
So I'm trying to write a simple genetic algorithm for solving a sudoku (not the most efficient way, I know, but it's just to practice evolutionary algorithms). I'm having some problems coming up with an efficient evaluation function to test if the puzzle is solved or not and how many errors there are. My first instinct would be to check if each row and column of the matrix (doing it in octave, which is similar to matlab) have unique elements by ordering them, checking for duplicates and then putting them back the way they were, which seems long winded. Any thoughts?
Sorry if this has been asked before...
Speedups:
Use bitwise operations instead of sorting.
I made 100 line sudoku solver in c it reasonably fast. For or super speed you need to implement DLX algorhitm, there is also some file on matlab exchange for that.
http://en.wikipedia.org/wiki/Exact_cover
http://en.wikipedia.org/wiki/Dancing_Links
http://en.wikipedia.org/wiki/Knuth's_Algorithm_X
#include "stdio.h"
int rec_sudoku(int (&mat)[9][9],int depth)
{
int sol[9][9][10]; //for eliminating
if(depth == 0) return 1;
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
sol[i][j][9]=9;
for(int k=0;k<9;k++)
{
if(mat[i][j]) sol[i][j][k]=0;
else sol[i][j][k]=1;
}
}
}
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
if(mat[i][j] == 0) continue;
for(int k=0;k<9;k++)
{
if(sol[i][k][mat[i][j]-1])
{
if(--sol[i][k][9]==0) return 0;
sol[i][k][mat[i][j]-1]=0;
}
if(sol[k][j][mat[i][j]-1])
{
if(--sol[k][j][9]==0) return 0;
sol[k][j][mat[i][j]-1]=0;
}
}
for(int k=(i/3)*3;k<(i/3+1)*3;k++)
{
for(int kk=(j/3)*3;kk<(j/3+1)*3;kk++)
{
if(sol[k][kk][mat[i][j]-1])
{
if(--sol[k][kk][9]==0) return 0;
sol[k][kk][mat[i][j]-1]=0;
}
}
}
}
}
for(int c=1;c<=9;c++)
{
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
if(sol[i][j][9] != c) continue;
for(int k=0;k<9;k++)
{
if(sol[i][j][k] != 1) continue;
mat[i][j]=k+1;
if(rec_sudoku(mat,depth-1)) return 1;
mat[i][j]=0;
}
return 0;
}
}
}
return 0;
}
int main(void)
{
int matrix[9][9] =
{
{1,0,0,0,0,7,0,9,0},
{0,3,0,0,2,0,0,0,8},
{0,0,9,6,0,0,5,0,0},
{0,0,5,3,0,0,9,0,0},
{0,1,0,0,8,0,0,0,2},
{6,0,0,0,0,4,0,0,0},
{3,0,0,0,0,0,0,1,0},
{0,4,0,0,0,0,0,0,7},
{0,0,7,0,0,0,3,0,0}
};
int d=0;
for(int i=0;i<9;i++) for(int j=0;j<9;j++) if(matrix[i][j] == 0) d++;
if(rec_sudoku(matrix,d)==0)
{
printf("no solution");
return 0;
}
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
printf("%i ",matrix[i][j]);
}
printf("\n");
}
return 1;
}
The check is easy, you'll create sets for rows, columns, and 3x3's adding a number if it does not exist and altering your fitness accordingly if it does not.
The real trick however is "altering your fitness" accordingly. Some problems seem well suited to GA and ES (evolution strategies), that is we look for a solution in tolerance, sudoku has an exact answer... tricky.
My first crack would probably be creating solutions with variable length chromosomes (well they could be fixed length but 9x9's with blanks). The fitness function should be able to determine which part of the solution is guaranteed and which part is not (sometimes you must take a guess in the dark in a really tough sudoku game and then back track if it does not work out), it would be a good idea to create children for each possible branch.
This then is a recursive solution. However you could start scanning from different positions on the board. Recombination would combine solutions which combine unverified portions which have overlapping solutions.
Just thinking about it in this high level easy going fashion I can see how mind bending this will be to implement!
Mutation would only be applied when there is more than one path to take, after all a mutation is a kind of guess.
Sounds good, except for the 'putting them back' part. You can just put the numbers from any line, column or square in the puzzle in a list and check for doubles any way you want. If there are doubles, there is an error. If all numbers are unique there's not. You don't need to take the actual numbers out of the puzzle, so there is no need for putting them back either.
Besides, if you're writing a solver, it should not make any invalid move, so this check would not be needed at all.
I would use the grid's numbers as an index, and increment an 9 elements length array's respective element => s_array[x]++ where x is the number taken from the grid.
Each and every element must be 1 in the array at the end of checking one row. If 0 occurs somewhere in the array, that line is wrong.
However this is just a simple sanity check if there are no problems, line-wise.
PS: if it were 10 years ago, I would suggest an assembly solution with bit manipulation (1st bit, 2nd bit, 3rd bit, etc. for the values 1,2 or 3) and check if the result is 2^10-1.
When I solved this problem, I just counted the number of duplicates in each row, column and sub-grid (in fact I only had to count duplicates in columns and sub-grids as my evolutionary operators were designed never to introduce duplicates into rows). I just used a HashSet to detect duplicates. There are faster ways but this was quick enough for me.
You can see this visualised in my Java applet (if it's too fast, increase the population size to slow it down). The coloured squares are duplicates. Yellow squares conflict with one other square, orange with two other squares and red with three or more.
Here is my solution. Sudoku solving solution in C++
Here is my solution using set. If for a line, a block or a column you get a set length of (let say) 7, your fitness would be 9 - 7.
If you are operating on a small set of integers sorting can be done in O(n) using bucket sorting.
You can use tmp arrays to do this task in matlab:
function tf = checkSubSet( board, sel )
%
% given a 9x9 board and a selection (using logical 9x9 sel matrix)
% verify that board(sel) has 9 unique elements
%
% assumptions made:
% - board is 9x9 with numbers 1,2,...,9
% - sel has only 9 "true" entries: nnz(sel) = 9
%
tmp = zeros(1,9);
tmp( board( sel ) ) = 1; % poor man's bucket sorting
tf = all( tmp == 1 ) && nnz(sel) == 9 && numel(tmp) == 9; % check validity
Now we can use checkSubSet to verify the board is correct
function isCorrect = checkSudokuBoard( board )
%
% assuming board is 9x9 matrix with entries 1,2,...,9
%
isCorrect = true;
% check rows and columns
for ii = 1:9
sel = false( 9 );
sel(:,ii) = true;
isCorrect = checkSubSet( board, sel );
if ~isCorrect
return;
end
sel = false( 9 );
sel( ii, : ) = true;
isCorrect = checkSubSet( board, sel );
if ~isCorrect
return;
end
end
% check all 3x3
for ii=1:3:9
for jj=1:3:9
sel = false( 9 );
sel( ii + (0:2) , jj + (0:2) ) = true;
isCorrect = checkSubSet( board, sel );
if ~isCorrect
return;
end
end
end
Consider the following 2 scenarios:
boolean b = false;
int i = 0;
while(i++ < 5) {
b = true;
}
OR
boolean b = false;
int i = 0;
while(i++ < 5) {
if(!b) {
b = true;
}
}
Which is more "costly" to do? If the answer depends on used language/compiler, please provide. My main programming language is Java.
Please do not ask questions like why would I want to do either.. They're just barebone examples that point out the relevant: should a variable be set the same value in a loop over and over again or should it be tested on every loop that it holds a value needed to change?
Please do not forget the rules of Optimization Club.
The first rule of Optimization Club is, you do not Optimize.
The second rule of Optimization Club is, you do not Optimize without measuring.
If your app is running faster than the underlying transport protocol, the optimization is over.
One factor at a time.
No marketroids, no marketroid schedules.
Testing will go on as long as it has to.
If this is your first night at Optimization Club, you have to write a test case.
It seems that you have broken rule 2. You have no measurement. If you really want to know, you'll answer the question yourself by setting up a test that runs scenario A against scenario B and finds the answer. There are so many differences between different environments, we can't answer.
Have you tested this? Working on a Linux system, I put your first example in a file called LoopTestNoIf.java and your second in a file called LoopTestWithIf.java, wrapped a main function and class around each of them, compiled, and then ran with this bash script:
#!/bin/bash
function run_test {
iter=0
while [ $iter -lt 100 ]
do
java $1
let iter=iter+1
done
}
time run_test LoopTestNoIf
time run_test LoopTestWithIf
The results were:
real 0m10.358s
user 0m4.349s
sys 0m1.159s
real 0m10.339s
user 0m4.299s
sys 0m1.178s
Showing that having the if makes it slight faster on my system.
Are you trying to find out if doing the assignment each loop is faster in total run time than doing a check each loop and only assigning once on satisfaction of the test condition?
In the above example I would guess that the first is faster. You perform 5 assignments. In the latter you perform 5 test and then an assignment.
But you'll need to up the iteration count and throw in some stopwatch timers to know for sure.
Actually, this is the question I was interested in… (I hoped that I’ll find the answer somewhere to avoid own testing. Well, I didn’t…)
To be sure that your (mine) test is valid, you (I) have to do enough iterations to get enough data. Each iteration must be “long” enough (I mean the time scale) to show the true difference. I’ve found out that even one billion iterations are not enough to fit to time interval that would be long enough… So I wrote this test:
for (int k = 0; k < 1000; ++k)
{
{
long stopwatch = System.nanoTime();
boolean b = false;
int i = 0, j = 0;
while (i++ < 1000000)
while (j++ < 1000000)
{
int a = i * j; // to slow down a bit
b = true;
a /= 2; // to slow down a bit more
}
long time = System.nanoTime() - stopwatch;
System.out.println("\\tasgn\t" + time);
}
{
long stopwatch = System.nanoTime();
boolean b = false;
int i = 0, j = 0;
while (i++ < 1000000)
while (j++ < 1000000)
{
int a = i * j; // the same thing as above
if (!b)
{
b = true;
}
a /= 2;
}
long time = System.nanoTime() - stopwatch;
System.out.println("\\tif\t" + time);
}
}
I ran the test three times storing the data in Excel, then I swapped the first (‘asgn’) and second (‘if’) case and ran it three times again… And the result? Four times “won” the ‘if’ case and two times the ‘asgn’ appeared to be the better case. This shows how sensitive the execution might be. But in general, I hope that this has also proven that the ‘if’ case is better choice.
Thanks, anyway…
Any compiler (except, perhaps, in debug) will optimize both these statements to
bool b = true;
But generally, relative speed of assignment and branch depend on processor architecture, and not on compiler. A modern, super-scalar processor perform horribly on branches. A simple micro-controller uses roughly the same number of cycles per any instruction.
Relative to your barebones example (and perhaps your real application):
boolean b = false;
// .. other stuff, might change b
int i = 0;
// .. other stuff, might change i
b |= i < 5;
while(i++ < 5) {
// .. stuff with i, possibly stuff with b, but no assignment to b
}
problem solved?
But really - it's going to be a question of the cost of your test (generally more than just if (boolean)) and the cost of your assignment (generally more than just primitive = x). If the test/assignment is expensive or your loop is long enough or you have high enough performance demands, you might want to break it into two parts - but all of those criteria require that you test how things perform. Of course, if your requirements are more demanding (say, b can flip back and forth), you might require a more complex solution.
Using this website i have tried to make a beat detection engine. http://www.gamedev.net/reference/articles/article1952.asp
{
ALfloat energy = 0;
ALfloat aEnergy = 0;
ALint beats = 0;
bool init = false;
ALfloat Ei[42];
ALfloat V = 0;
ALfloat C = 0;
ALshort *hold;
hold = new ALshort[[myDat length]/2];
[myDat getBytes:hold length:[myDat length]];
ALuint uiNumSamples;
uiNumSamples = [myDat length]/4;
if(alDatal == NULL)
alDatal = (ALshort *) malloc(uiNumSamples*2);
if(alDatar == NULL)
alDatar = (ALshort *) malloc(uiNumSamples*2);
for (int i = 0; i < uiNumSamples; i++)
{
alDatal[i] = hold[i*2];
alDatar[i] = hold[i*2+1];
}
energy = 0;
for(int start = 0; start<(22050*10); start+=512){
for(int i = start; i<(start+512); i++){
energy+= ((alDatal[i]*alDatal[i]) + (alDatal[i]*alDatar[i]));
}
aEnergy = 0;
for(int i = 41; i>=0; i--){
if(i ==0){
Ei[0] = energy;
}
else {
Ei[i] = Ei[i-1];
}
if(start >= 21504){
aEnergy+=Ei[i];
}
}
aEnergy = aEnergy/43.f;
if (start >= 21504) {
for(int i = 0; i<42; i++){
V += (Ei[i]-aEnergy);
}
V = V/43.f;
C = (-0.0025714*V)+1.5142857;
init = true;
if(energy >(C*aEnergy)) beats++;
}
}
}
alDatal and alDatar are (short*) type;
myDat is NSdata that holds the actual audio data of a wav file formatted to
22050 khz and 16 bit stereo.
This doesn't seem to work correctly. If anyone could help me out that would be amazing. I've been stuck on this for 3 days.
The desired result is after the 10 seconds worth of data has been processed i should be able to multiply that by 6 and have an estimated beats per minute.
My current results are 389 beats every 10 seconds, 2334 BPM the song i know is right around 120 BPM.
That code really has been smacked about with the ugly stick. If you're going to ask other people to find your bugs for you, it's a good idea to make things presentable first. Strangely enough, this will often help you to find them for yourself too.
So, before I point out some of the more fundamental errors, I have to make a few schoolmarmly suggestions:
Don't sprinkle your code with magic numbers. Is it really that hard to type a few lines like const ALuint SAMPLE_RATE = 22050? Trust me, it makes life a lot easier.
Use variable names that you aren't going to mix up easily. One of your bugs is a substitution of alDatal for alDatar. That probably wouldn't have happened if they were called left and right. Similarly, what is the point of having a meaningful variable name like energy if you're just going to stick it alongside the meaningless but more or less identical aEnergy? Why not something informative like average?
Declare variables close to where you're going to use them and in the appropriate scope. Another of your bugs is that you don't reset your calculated energy sum when you move your averaging window, so the energy will just add up and up. But you don't need the energy outside that loop, and if you declared it inside the problem couldn't happen.
There are some other things I personally find a little irksome, like the random bracing and indentation, and mixing of C and C++ allocations, and odd inconsistent scraps of Hungarian prefixing, but at least some of those may be more a matter of taste so I won't go on.
Anyway, here are some reasons why your code doesn't work:
First up, look at the right hand side of this line:
energy+= ((alDatal[i]*alDatal[i]) + (alDatal[i]*alDatar[i]));
You want the square of each channel value, so it should really say:
energy+= ((alDatal[i]*alDatal[i]) + (alDatar[i]*alDatar[i]));
Spot the difference? Not easy with those names, is it?
Second, you should be computing the total energy over each window of samples, but you're only setting energy = 0 outside the outer loop. So the sum accumulates, and consequently the current window energy will always be the biggest you've ever encountered.
Third, your variance calculation is wrong. You have:
V += (Ei[i]-aEnergy);
But it should be the sum of the squares of the differences from the mean:
V += (Ei[i] - aEnergy) * (Ei[i] - aEnergy);
There may well be other errors as well. For instance, you don't allocate the data buffers if they're not NULL, but assume that they're the right length -- which you've only just calculated. You may justify that in terms of some consistent usage you've stuck to throughout your code, but from the perspective of what we can see here it looks like a pretty bad idea.
I have the following method that should create a 20 character ID (sometimes with a prefix) and return the ID.
It seems to reset on launch and every time I use it it will create the same succession of identical numbers.
+(NSString *)createUniqueIdentifier:(NSString *)withPrefix {
NSString *outstring = nil;
if (withPrefix!=nil && ![withPrefix isEqualToString:#""]) {
outstring = [withPrefix stringByAppendingString:#"-"];
} else {
outstring = #"";
}
NSInteger ii;
NSString *allletters = #"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (ii=0; ii<20; ii++) {
outstring = [outstring stringByAppendingString:[allletters substringWithRange:[allletters rangeOfComposedCharacterSequenceAtIndex:random()%[allletters length]]]];
}
return outstring;
}
I'm assuming this has something to do with random(), but I don't know what else to use. I think I even got that suggestion from Stack Overflow.
Thanks for any help!
When using random() you should set the seed value at program start, ie srandom(time(NULL));
My guess is that you probably need to set the seed since it'll use a default one if you don't.
You should at least use something based on the date/time to get something that varies for each run.
If you'd like a completely unique string, I'd use NSProcessInfo to generate one for you by calling:
[[NSProcessInfo processInfo] globallyUniqueString];
Unless you only want it to contain those letters mentioned.
I think I've figured it out. I changed random() to arc4random() and it magically seems to work now.
Here's the documentation on arc4random that probably has something to do with it:
The arc4random() function uses the key stream generator employed by the arc4 cipher, which uses 8*8 8 bit S-Boxes. The S-Boxes can be in about (21700) states. The arc4random() function returns pseudo-random numbers in the range of 0 to (232)-1, and therefore has twice the range of rand(3) and random(3) .
The arc4random_stir() function reads data from /dev/urandom and uses it to permute the S-Boxes via arc4random_addrandom().
There is no need to call arc4random_stir() before using arc4random(), since arc4random() automatically initializes itself.
FYI: If you absolutely need unique strings, create a UUID instead of using random, which has a minute chance of getting identical values.
I have used rand(). But it gives a specific value even after I restart application.
I have implemented following in my application.
- (void)viewDidLoad {
[super viewDidLoad];
int x,y;
x=random() % 480; y=random() % 300;
lblT.center=CGPointMake(x,y); // my label lblT
}
Try to implement in your application, and launch application.
After restarting application, you will find that label will be on specific value.
arc4random() is a built-in function that does not require seeding (and so therefore does not produce predictable sequences that can be generated by using a seed), and it conveniently returns integers. I never use anything else.
Use the following line before random()
srand(time(NULL));
Random number generators in software will actually give PSEUDORANDOM sequences of values.
Unless you seed the random number generator with a value from a truly random event, you will always get the same sequence each time you use the software.
I don't know about your software, but it doesn't look like you're seeding the random number generator, Gcamp is probably on the right track.
Since you are using random() and not rand() you should seed the random generator with this bit of code...
srandomdev();
I would do it like this:
landscape:
- (void)viewDidLoad {
[super viewDidLoad];
int x = arc4random()%480;
int y = arc4random()%320;
lblT.center=CGPointMake(x,y);
}
not landscape:
- (void)viewDidLoad {
[super viewDidLoad];
int x = arc4random()%320;
int y = arc4random()%480;
lblT.center=CGPointMake(x,y);
}
use this code, only for Integer random values
#define random(min,max) ((arc4random() % (max-min+1)) + min)
testing
for (int i = 0; i < 500; i++) {
NSLog(#"rand is %d", random(-100,100));
}