Go Down

Topic: a varying amount of randomness (Read 389 times) previous topic - next topic

Laktica

I want to shuffle an array, simple! There are many  examples of code to do this, but the problem is, I want to be able to vary the amount of shuffle.

I have found lots of info on Random number generation, and pseudo-random numbers and their generation techniques.
I have also read up on shuffle algorithms and their importance in some cases


But my implementation is for sequencing lights so the TRUE randomness of the shuffle is not important but the ability to vary the degree of shuffle is.

I.e. I don't care if the output isn't absolutely bias free random, so long as I can change the amount of shuffle down to say 50% and see some (half ideally) of the original sequence taking place

Here's what I wrote, I'd love your feedback and thoughts, not sure how efficient this is or if there's other ways of doing it so looking forward to some suggestions.

Cheers

Code: [Select]
// Shuffles values in an array by swapping around 2 random slots, by designating the amount of swaps you can adjust the shuffle amount
// Not much amount range for small arrays  -  May be too clumsy/time consuming for large arrays
// if array has 20 elements 10 swapcount renders all values shuffled.   5 swapcounts = 50% shuffled

int Temp1;
int Temp2;
int OrgPos;
int SwapPos;
int SwapCount=0;
int LoopCount=0;

int StepPos[16] = {       // array with elements numbered from 0 to 19
  1,  2,  3,  4,  5,  6,  7,  8,  9,  10,  11,  12,  13,  14,  15, 16, 17, 18, 19, 20  };
// 0   1   2   3   4   5   6   7   8    9   10   11   12   13   14  15  16  17  18  19

int SeqFor[16] = {       // array initializer for comparing
  1,  2,  3,  4,  5,  6,  7,  8,  9,  10,  11,  12,  13,  14,  15, 16, 17, 18, 19, 20  };
// 0   1   2   3   4   5   6   7   8    9   10   11   12   13   14  15  16  17  18  19

void setup() {
 Serial.begin(28800);
 randomSeed(analogRead(0));
}

void loop() {
 if (SwapCount == 0){
     Serial.print(" StartTime ");
     Serial.println(millis());
 }
tryagain:
 OrgPos = random(0,16);                            // choose random table slot and save as OrgPos
 if (StepPos[OrgPos] == SeqFor[OrgPos]){           // is StepPos[OrgPos] equal to seqFor[OrgPos]
   Temp1 =  StepPos[OrgPos];                       // if is copy val to Temp1  - end if
 }
 else goto tryagain;                               // if not try again
tryagain2:
 SwapPos = random (0,16);                          // choose random table slot and save as SwapPos
 if (StepPos[SwapPos] == SeqFor[SwapPos] && SwapPos != OrgPos){   // is StepPos[SwapPos] equal to seqFor[SwapPos] and not same as OrgPos
   Temp2 =  StepPos[SwapPos];                      // if is copy val to Temp2
   StepPos[OrgPos] =  Temp2;                       // Paste Temp2 to OrgPos
   StepPos[SwapPos] = Temp1;                       // Paste Temp1 to SwapPos
   SwapCount++;                                    // increse swap counter  - end if
 }          
 else goto tryagain2;                              // if not try again    

 LoopCount++;                                      // for testing only


 ///////For Testing
//    for (int i=0; i<16; i++){
//      Serial.print(StepPos[i]);
//      Serial.print("-");
//    }
//    Serial.print("   Swap Count: ");
//    Serial.print(SwapCount);
//     Serial.print("   Loop Count: ");
//   Serial.println(LoopCount);
//    for (int i=0; i<16; i++){
//      Serial.print(SeqFor[i]);
//      Serial.print("-");
//    }
//    Serial.print("   OrgPos");
//    Serial.print(OrgPos+1);
//    Serial.print("   SwapPos");
//    Serial.print(SwapPos+1);
//    Serial.print("  -");
//    Serial.println();
//    Serial.println();




 if (StepPos[0]   != SeqFor[0]  && StepPos[1]  != SeqFor[1]  && StepPos[2]  != SeqFor[2]
   && StepPos[3]  != SeqFor[3]  && StepPos[4]  != SeqFor[4]  && StepPos[5]  != SeqFor[5]
   && StepPos[6]  != SeqFor[6]  && StepPos[7]  != SeqFor[7]  && StepPos[8]  != SeqFor[8]
   && StepPos[9]  != SeqFor[9]  && StepPos[10] != SeqFor[10] && StepPos[11] != SeqFor[11]
   && StepPos[12] != SeqFor[12] && StepPos[13] != SeqFor[13] && StepPos[14] != SeqFor[14]
   && StepPos[15] != SeqFor[15]){

     Serial.print(" ENDTime ");
     Serial.println(millis());


   // comment out above 'for testing' or this part with reset
   for (int i=0; i<16; i++){
     Serial.print(StepPos[i]);
     Serial.print("-");
   }
   Serial.print("    All Random");
   Serial.println();
   for (int i=0; i<16; i++){
     Serial.print(SeqFor[i]);
     Serial.print("-");
   }
   Serial.print("    All Original");
   //reset
   Serial.println();
   for (int l=0; l<=15; l++) {
     StepPos[l] = SeqFor[l];
   }    
  SwapCount=0;
   Serial.println();
 }
}






Grumpy_Mike

If I were doing it I would generate two random numbers and use them to swap the two array elements. The degree of shuffle is then just how many times you do this.

Laktica

Aren't I?

is generating two random numbers different to generating a single random number twice? through the loop?

can you elaborate a little?

Also, thanks for pointing out, I didn't mention the fact the sample code doesn't include the 'pot reading'  'mapping' and 'how many times to swap' functionality but as I have a swap counter i figured i'd just do this bit afterward

lloyddean

#3
Feb 03, 2012, 12:02 am Last Edit: Feb 03, 2012, 12:09 am by lloyddean Reason: 1
Your use of 'goto' can easily be replaced with ...

Code: [Select]

   while ( true )
   {
       OrgPos = random(0, 16);
       if ( StepPos[OrgPos] == SeqFor[OrgPos] )
       {
           Temp1               = StepPos[OrgPos];
           break;
       }
   }
   
   while ( true )
   {
       SwapPos = random(0, 16);
       if ( StepPos[SwapPos] == SeqFor[SwapPos] && SwapPos != OrgPos)
       {
           Temp2               = StepPos[SwapPos];
           StepPos[OrgPos]     = Temp2;
           StepPos[SwapPos]    = Temp1;
           SwapCount++;
           break;
       }          
   }


... and your comments are redundant as they don't say anything different than the code.

Laktica

ahh nice, i know goto was baaaad and there was a way, cheers

Quote
... and your comments are redundant as they don't say anything different than the code.


hahah agreed, i wrote it out like that first in word on work pc then typed it properly formatted in the IDE at home, they are useless sorry


lloyddean

You're going to have to give a MUCH better description of what you wish to accomplish, with examples preferably.

Go Up