none
Shuffling an image array C#

    Question

  • Hey guys,

    I was trying to Shuffle a list of images and I was wondering if there was a quick and simple way of doing it.  Could you also show me the algorithm for it? I am doing a school assignment but I will change around the algorithm to suit my images (P.S. I am allowed to do this). 

    Thursday, October 11, 2012 9:10 AM

Answers

All replies

  • U can just use something like this——This is my example to shuffle the numbers from 1 to 55000 at a random order:

    namespace CSharp
    {
        public class MainTest
        {
            static List<int> RandomNumbers(int from, int to)
            {
                List<int> numbers = new List<int>();
                Random r = new Random(Guid.NewGuid().GetHashCode());
    
                for (int i = from; i <=to; i++)
                {
                    numbers.Insert(r.Next(0, numbers.Count), i);
                }
                return numbers;
            }
    
            static void Main(string[] args)
            {
                //打印55000个数字
                int counter = 1;
                foreach (var item in RandomNumbers(1,55000))
                {
                    Console.Write(item + ",");
                    counter++;
                    if (counter == 10)
                    {
                        Console.WriteLine();
                        counter = 1;
                    }
                }
            }
        }
    }

    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处


    Thursday, October 11, 2012 9:13 AM
  • Right, I don't fully understand and didn't use this but I suppose it can be helpful for someone else, thanks for responding. 
    Friday, October 12, 2012 9:11 AM
  • Right, I don't fully understand and didn't use this but I suppose it can be helpful for someone else, thanks for responding. 
    In fact u can just save ur image indexes inside the array, and then shuffle my array like the way I mean above.

    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    Friday, October 12, 2012 12:50 PM
  • Check this, it is a trick of using random numbers in an array

     public static Image[] ShuffleImages(Image[] arr)
     {
                List<KeyValuePair<int, Image>> list = new List<KeyValuePair<int, Image>>();
                // Add all Images from array
                // Add new random int each time
                foreach (Image im in arr)
                {
                    list.Add(new KeyValuePair<int, Image>(_random.Next(), im));
                }
                // Sort the list by the random number
                var sorted = from item in list
                             orderby item.Key
                             select item;
                Image[] result = new Image[arr.Length];
                // Copy shuffle array to result
                int index = 0;
                foreach (KeyValuePair<int, Image> pair in sorted)
                {
                    result[index] = pair.Value;
                    index++;
                }
                return result;
            }

    Friday, October 12, 2012 7:43 PM
  • You don't need an intermediate list to sort by a random number:
    public static Image[] ShuffleImages(Image[] arr)
    {
        return (from image in arr
                orderby _random.Next()
                select image).ToArray();
    }
    You can also use the Array.Sort method:
    public static void ShuffleImages(Image[] arr)
    {
        int[] randomNumbers = new int[arr.Length];
        for (int i = 0; i < randomNumbers.Length; i++)
        {
            randomNumbers[i] = _random.Next();
        }
        Array.Sort(arr, randomNumbers);
    }


    Monday, October 15, 2012 11:40 AM
  • You don't need an intermediate list to sort by a random number:
    public static Image[] ShuffleImages(Image[] arr)
    {
        return (from image in arr
                orderby _random.Next()
                select image).ToArray();
    }
    You can also use the Array.Sort method:
    public static void ShuffleImages(Image[] arr)
    {
        int[] randomNumbers = new int[arr.Length];
        for (int i = 0; i < randomNumbers.Length; i++)
        {
            randomNumbers[i] = _random.Next();
        }
        Array.Sort(arr, randomNumbers);
    }

    Both of these are poor methods of shuffling an array.  The first is particularly bad.  Sorting algorithms rely on having a stable comparator.  It relies on several underlying assumptions that the code you have provided violates.  It assumes that if A>B that B<A.  If you create a new random number for each comparison that may not be true.  Next, even if the sort "works", it's not going to evenly distribute the items.  They are more likely to end up nearer to where they started.  Your second approach solves all of those problems by computing the random numbers before starting.  Both of the approaches also have the flaw of being O(n * log(n)) complexity though, whereas a shuffle only actually needs to be O(n).

    You can find information about shuffling here.  The psudocode for the simplest method is:

    To shuffle an array a of n elements (indices 0..n-1):
      for i from n - 1 downto 1 do
           j ← random integer with 0 ≤ j ≤ i
           exchange a[j] and a[i]

     
    Monday, October 15, 2012 2:58 PM
  • Sorting algorithms rely on having a stable comparator. It relies on several underlying assumptions that the code you have provided violates. It assumes that if A>B that B<a. If you create a new random number for each comparison that may not be true.

    Fortunately I don't do that. I put an expression in the orderby clause; I didn't provide a comparer with a random result.

    Both of the approaches also have the flaw of being O(n * log(n)) complexity though

    Note that I was only modifying code that I thought could be improved. The goal was not to propose another algorithm but to show how that one could be improved.

    The psudocode for the simplest method is:

    I know that code quite well. I even think I have proposed it in another thread in another time.

    Tuesday, October 16, 2012 7:33 AM