views:

125

answers:

2

I am looking to randomly shuffle a list/array using a key. I want to be able to repeat the same random order using the key.

So I will randomly generate a numeric key from say 1 to 20 then use that key to try and randomly shuffle the list.

I first tried just using the key to keep iterating through my list, decrementing the key until=0, then grabbing whatever element I am on, removing it and adding it to my shuffled array. The result is kind of random but when the arrays are small (which most of mine will be) and/or the key is small it doesn't end up shuffling... seems to be more of a shift.

I have to be able to determine what order the

Here is some sample code in csharp of :

public static TList<VoteSetupAnswer> ShuffleListWithKey(TList<VoteSetupAnswer> UnsortedList, int ShuffleKey)
    {
        TList<VoteSetupAnswer> SortedList = new TList<VoteSetupAnswer>();
        int UnsortedListCount = UnsortedList.Count;
        for (int i = 0; i < UnsortedListCount; i++)
        {
            int Location;
            SortedList.Add(OneArrayCycle(UnsortedList, ShuffleKey, out Location));
            UnsortedList.RemoveAt(Location);
        }
        return SortedList;
    }

    public static VoteSetupAnswer OneArrayCycle(TList<VoteSetupAnswer> array, int ShuffleKey, out int Location)
    {
        Location = 0;
        if (ShuffleKey == 1)
        {
            Location = 0;
            return array[0];
        }
        else
        {
            for (int x = 0; x <= ShuffleKey; x++)
            {
                if (x == ShuffleKey)
                    return array[Location];
                Location++;
                if (Location == array.Count)
                    Location = 0;
            }
            return array[Location];
        }
    }
+1  A: 

Do a random permutation, seed the RNG with your key.

 /**
     * Randomly permutes the array of this permutation. All permutations occur with approximately equal
     * likelihood. This implementation traverses the permutation array forward, from the first element up to
     * the second last, repeatedly swapping a randomly selected element into the "current position". Elements
     * are randomly selected from the portion of the permutation array that runs from the current position to
     * the last element, inclusive.
     * <p>
     * This method runs in linear time.
     */
    public static void shuffle(Random random, int[] a) {
        for (int i = 0; i < a.length - 1; i++) {
            swap(a, i, i + random.nextInt(a.length - i));
        }
    }
bmargulies
Thank you for the reply. If I wanted to repeat the same ordering of my array there would be no way to do thia as random.nextInt will return different number everytime called. I need a way to reproduce the same shuffle order
Seed the random class with a fixed seed.
bmargulies
A: 

Implement something like Fisher-Yates. Don't roll your own. It's likely to be wrong. Seed the Random constructor with a specified value. The shuffle will then be repeatable.

Alternatively, this can be done nicely with linq:

var key=0;
var r=new Random(key);
myList.OrderBy(x=>r.Next());

Change the value of key to change the shuffle.

spender
I am not using Linq. But this is interesting. The .OrderBy can take an index rather than a field. So it sorts ascending on a random field then?
Well, it's not really sorting "by a field" but evaluating the value of a field. This needn't necessarily be a property of the lambda parameter (x in the case above), but anything in scope.
spender