To expand upon my comment...
Firstly, be sure that you can't do this shuffle in physical memory. If you have fewer than UInt32.MaxValue
items you can still use managed arrays. Plus you only need to store an int
(or possibly long
) per item, not the item itself.
So, you have so many items you can't count them in memory?
Start off by storing a number for each item in a file.
using (var f = File.Create("shuffle.bin"))
{
var length = A.Count * B.Count * C.Count;
f.SetLength(length * sizeof(long));
for (long i = 0; i < length; i++)
{
var bytes = BitConverter.GetBytes(i);
f.Write(bytes, 0, sizeof(long));
}
}
It would take forever to shuffle this file. So instead, we can shuffle one entry out at a time, on demand. This shouldn't take too long to extract one number.
using (var f = File.Open("shuffle.bin", FileMode.Open))
{
// Calculate how many numbers are left in the file.
long itemCount = f.Length / sizeof(long);
if (itemCount == 0)
{
// We have used all the items - create another file, or throw
// an exception, or whatever you want.
}
// You need an equivalent of `Random.Next(int max)` here that works on `long`s.
long index = NextLong(itemCount);
// Read out the number you've shuffled out.
f.Seek(index * sizeof(long), SeekOrigin.Begin);
var rtnBytes = new byte[sizeof(long)];
f.Read(rtnBytes, 0, sizeof(long));
// Read out the last number.
f.Seek((itemCount - 1) * sizeof(long), SeekOrigin.Begin);
var rplcBytes = new byte[sizeof(long)];
f.Read(rplcBytes, 0, sizeof(long));
// Replace the shuffled-out number with the last number.
f.Seek(index * sizeof(long), SeekOrigin.Begin);
f.Write(rplcBytes, 0, sizeof(long));
// Trim the now-duplicate last number off the end of the file.
f.SetLength((itemCount - 1) * sizeof(long));
// Get the long and do with it what you want.
long rtnLong = BitConverter.ToInt64(rtnBytes, 0);
}
You can then turn this long
into a triple of indices as follows:
int indexA = (int)(rtnLong % (long)A.Count);
rtnLong /= a.Count;
int indexB = (int)(rtnLong % (long)B.Count);
rtnLong /= b.Count;
int indexC = (int)rtnLong;
>](http://stackoverflow.com/questions/545703/combination-of-listlistint) but the first answer is pretty much exactly what you want, possibly followed by shuffling the result.
– Rawling Nov 27 '13 at 12:50