in reply to Music shuffling

Surprisingly, (that is, against my own intuition) it does seem remarkably fair.

If you do just N * 2 cycles (-I=100) it occasionally only picks 48 or 49 of the 50 possibles, but other times it will have picked all 50, which seems well within the bounds of probability. And if you run it for 1e6 cycles, the distribution seems very even. Given the lousy performance of the default rand on my system, it again all seems to be well within statistical boundaries:

#! perl -slw use strict; my @tracks = 1 .. 50; my %picks; our $I ||= 1e5; for ( 1 .. $I ) { push @tracks, splice @tracks, rand( @tracks/2 ), 1; printf "$tracks[ -1 ] " unless $picks{ $tracks[ -1 ] }; $picks{ $tracks[ -1 ] }++; } print "\nPercentage picked: ", keys( %picks ) / @tracks * 100; printf "track %2d picked %5d times\n", $_, $picks{ $_ } for sort{ $picks{ $b } <=> $picks{ $a } } keys %picks; __END__ c:\test>junk6 -I=1e6 1 14 18 23 7 5 28 26 3 16 33 36 8 17 30 4 40 24 2 39 34 9 35 11 46 25 47 15 49 37 50 19 41 6 38 21 10 20 44 13 43 12 27 42 45 29 22 31 48 32 Percentage picked: 100 track 14 picked 20145 times track 35 picked 20124 times track 25 picked 20117 times track 12 picked 20109 times track 40 picked 20104 times track 10 picked 20102 times track 30 picked 20087 times track 4 picked 20086 times track 11 picked 20075 times track 16 picked 20073 times track 47 picked 20068 times track 18 picked 20065 times track 2 picked 20050 times track 7 picked 20045 times track 26 picked 20041 times track 24 picked 20038 times track 39 picked 20038 times track 45 picked 20038 times track 20 picked 20031 times track 48 picked 20031 times track 8 picked 20029 times track 38 picked 20027 times track 5 picked 20021 times track 6 picked 20015 times track 15 picked 20014 times track 28 picked 20002 times track 13 picked 19985 times track 34 picked 19981 times track 50 picked 19980 times track 9 picked 19977 times track 17 picked 19976 times track 37 picked 19975 times track 32 picked 19966 times track 23 picked 19964 times track 21 picked 19961 times track 1 picked 19957 times track 41 picked 19953 times track 36 picked 19947 times track 42 picked 19946 times track 44 picked 19936 times track 3 picked 19934 times track 43 picked 19931 times track 49 picked 19921 times track 29 picked 19914 times track 27 picked 19901 times track 31 picked 19889 times track 19 picked 19887 times track 22 picked 19879 times track 46 picked 19874 times track 33 picked 19791 times

That said. Shuffling once and then just picking from the front would seem to be easier.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^2: Music shuffling
by oko1 (Deacon) on Jul 08, 2008 at 16:27 UTC

    What a great analysis - thank you and ++! My problem here, I suppose, is that I'm not much of a mathematician (hangs head in shame) - I know how to do a frequency count - I just didn't think of doing one to analyze this thing for fairness.

    That said. Shuffling once and then just picking from the front would seem to be easier.

    Wouldn't that still leave a possible collision problem at the point where the two lists join? Or did I misunderstand what you're describing?

    
    -- 
    Human history becomes more and more a race between education and catastrophe. -- HG Wells
    
      Wouldn't that still leave a possible collision problem at the point where the two lists join?

      Which two lists? ;)

      Assuming a single list of tracks:

      use List::Util qw[ shuffle ]; my @tracks = shuffle readTracks( 'myMusicDB' ); while( $listening ) { push @tracks, ( my $nextTrack = shift @tracks ); play $nextTrack; }

      By shuffling all your tracks once, when you load them, and then picking from the front (shifting) and replacing at the back (pushing), you are guarenteed to never hear the same track again until you've heard every other track. And you'll never know what track is coming next in any given cycle.

      If your list is short and you resent being able to predict what you will hear next when the loop repeats, you could always remember the first track (post shuffle) and re-shuffle when it comes around again.

      Of course that leaves you open to the possibility of hearing the same track twice in succession when you re-shuffle. Which I guess is what you mean by "two lists".

      My math is pretty much limited to "arithmetic", also. That is, without I go look up the particular more advanced stuff I need for any particular thing. A side-effect of of a career of general programming as opposed to consitantly working in a particular field. A bit like a GP versus a consultant. You may cover much of the ground briefly during training, but you either use it, or loose it!


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        Which two lists? ;)

        I think you got it. :) I was, of course, speaking of any two successive lists resulting from the shuffling.

        The randomizing approach I mentioned in my response to jethro would deal with that, though. Here's a shot at it in code:

        #!/usr/bin/perl -w use strict; use List::Util qw[ shuffle ]; my @tracks = 1..100; my $range = 5; # No overlap for this number of songs { my @last; for (@tracks){ unshift @last, $_; @last = @last[0..4] if @last > 5; # Play it! print "$_\n"; } my %h; do { # print "Shuffling...\n"; @tracks = shuffle @tracks; @h{@last,@tracks[0..4]} = (1) x $range * 2; } while keys %h < $range * 2; # For demo purposes... sleep 5; redo; }

        The repeated shuffling mechanism kicks off a lot if $range is close to @tracks / 2; that makes for a good test.

        
        -- 
        Human history becomes more and more a race between education and catastrophe. -- HG Wells