Pages: [1]   Go Down
Author Topic: a varying amount of randomness  (Read 326 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
// 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();
  }
}




Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 596
Posts: 33283
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Des Moines, WA - USA
Offline Offline
God Member
*****
Karma: 25
Posts: 779
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your use of 'goto' can easily be replaced with ...

Code:
   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.
« Last Edit: February 02, 2012, 06:09:03 pm by lloyddean » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Logged

Des Moines, WA - USA
Offline Offline
God Member
*****
Karma: 25
Posts: 779
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pages: [1]   Go Up
Jump to: