Пример #1
0
        private void LongRandomArraysInner(int len, IRandomSource rng)
        {
            // Create random array.
            int[] keys = CreateRandomArray(len, rng);

            // For the vals array, use a copy of the keys, but add a large constant so that we
            // can be sure keys weren't just copied by accident into vals(!).
            const int offset = 1_000_000;

            int[] vals = (int[])keys.Clone();
            for (int i = 0; i < vals.Length; i++)
            {
                vals[i] += offset;
            }

            // Sort array.
            TimSort <int, int> .Sort(keys, vals);

            // Check array is sorted.
            Assert.IsTrue(SortUtils.IsSortedAscending(keys));

            // Checks vals.
            for (int i = 0; i < keys.Length; i++)
            {
                Assert.AreEqual(keys[i] + offset, vals[i]);
            }
        }
Пример #2
0
        public void Sort_ShortArray()
        {
            int[] keys = new int[] { 5, 8, 2, 16, 32, 12, 7 };
            TimSort <int> .Sort(keys);

            Assert.True(SpanUtils.Equal <int>(new int[] { 2, 5, 7, 8, 12, 16, 32 }, keys));
        }
        private static int[] CompileNodeIdMap(
            GraphDepthInfo depthInfo,
            int nodeCount,
            int inputCount,
            ref int[] timsortWorkArr,
            ref int[] timsortWorkVArr)
        {
            // Create an array of all node IDs in the digraph.
            int[] nodeIdArr = new int[nodeCount];
            for (int i = 0; i < nodeCount; i++)
            {
                nodeIdArr[i] = i;
            }

            // Sort nodeIdArr based on the depth of the nodes.
            // Notes.
            // We skip the input nodes because these all have depth zero and therefore remain at fixed
            // positions.
            //
            // The remaining nodes (output and hidden nodes) are sorted by depth, noting that typically
            // there will be multiple nodes at a given depth. Here we apply the TimSort algorithm; this
            // has very good performance when there are pre-sorted sub-spans, either in the correct
            // direction or in reverse, as is typical of much real world data, and is likely the case here
            // too.
            //
            // Timsort also performs a stable sort, as it is based on a mergesort (note. at time of writing
            // Array.Sort employs introsort, which is not stable), thus avoids unnecessary shuffling of nodes
            // that are at the same depth. However the use of a stable sort is not a strict requirement here.
            //
            // Regarding timsort temporary working data.
            // Depending on the data being sorted, timsort may use a temp array with up to N/2 elements. Here
            // we ensure that the maximum possible size is allocated, and we re-use these arrays in future
            // calls. If instead we pass null or an array that is too short, then timsort will allocate a new
            // array internally, per sort, so we want to avoid that cost.

            // ENHANCEMENT: Modify TimSort class to accept working arrays by ref, so that if a larger array was allocated internally, we receive it back here.
            // Thus we achieve the same functionality without requiring knowledge of TimSort's internal logic.
            // Allocate new timsort working arrays, if necessary.
            int timsortWorkArrLength = nodeCount >> 1;

            if (null == timsortWorkArr || timsortWorkArr.Length < timsortWorkArrLength)
            {
                timsortWorkArr  = new int[timsortWorkArrLength];
                timsortWorkVArr = new int[timsortWorkArrLength];
            }

            // Sort the node IDs by depth.
            TimSort <int, int> .Sort(depthInfo._nodeDepthArr, nodeIdArr, inputCount, nodeCount - inputCount, timsortWorkArr, timsortWorkVArr);

            // Each node is now assigned a new node ID based on its index in nodeIdArr, i.e.
            // we are re-allocating IDs based on node depth.
            // ENHANCEMENT: This mapping inversion is avoidable if the consumer of the mapping is modified to consume the 'old index to new index' mapping.
            int[] newIdByOldId = new int[nodeCount];
            for (int i = 0; i < nodeCount; i++)
            {
                newIdByOldId[nodeIdArr[i]] = i;
            }

            return(newIdByOldId);
        }
Пример #4
0
 public void SortNaturalRandom()
 {
     for (int i = 0; i < _arrays.Length; i++)
     {
         TimSort <int> .Sort(_arrays[i], ref _work);
     }
 }
Пример #5
0
        /// <summary>
        /// This Mating Pool Selector returns a pool of the fittest entities from the supplied population.
        /// </summary>
        /// <param name="pPopulation"></param>
        /// <param name="pSize"></param>
        /// <returns>List of GeneticEntity</returns>
        public List <T> SelectPool <T>(List <T> pPopulation, int pSize) where T : GeneticEntity
        {
            T[] matingArray = pPopulation.ToArray();
            TimSort <T> .sort(matingArray, new GeneticEntityComparable());

            return(new List <T>(matingArray));
        }
Пример #6
0
 public void SortRandom()
 {
     for (int i = 0; i < _arrays.Length; i++)
     {
         TimSort <int, int> .Sort(_arrays[i], _vals, ref _work, ref _workv);
     }
 }
Пример #7
0
        public void ShortArray()
        {
            int[] keys = new int[] { 5, 8, 2, 16, 32, 12, 7 };
            TimSort <int> .Sort(keys);

            Assert.IsTrue(ArrayUtils.Equals(new int[] { 2, 5, 7, 8, 12, 16, 32 }, keys));
        }
Пример #8
0
        /// <summary>
        /// This Breeding Pair Selector returns pairings descend sequentially in fitness.
        /// </summary>
        /// <param name="pPopulation"></param>
        /// <returns>List of GeneticEntity</returns>
        public List <T> SelectPairs <T>(List <T> pPopulation) where T : GeneticEntity
        {
            T[] popArray = pPopulation.ToArray();
            TimSort <T> .sort(popArray, new GeneticEntityComparable());

            return(new List <T>(popArray));
        }
Пример #9
0
        public void StackSizeExceptionTest2B()
        {
            int[] arr = new TimSortStackSize2(1_073_741_824).CreateArray();
            TimSort <int> .Sort(arr);

            // While we're here, check the sort actually worked.
            Assert.True(SortUtils.IsSortedAscending <int>(arr));
        }
Пример #10
0
        public void StackSize2()
        {
            int[] arr = new TimSortStackSize2(67_108_864).CreateArray();
            TimSort <int> .Sort(arr);

            // While we're here, check the sort actually worked.
            Assert.IsTrue(SortUtils.IsSortedAscending(arr));
        }
Пример #11
0
        public void ShortArray()
        {
            int[] keys = new int[] { 5, 8, 2, 16, 32, 12, 7 };
            int[] vals = new int[] { 0, 1, 2, 3, 4, 5, 6 };
            TimSort <int, int> .Sort(keys, vals);

            Assert.IsTrue(ArrayUtils.Equals(new int[] { 2, 5, 7, 8, 12, 16, 32 }, keys));
            Assert.IsTrue(ArrayUtils.Equals(new int[] { 2, 0, 6, 1, 5, 3, 4 }, vals));
        }
Пример #12
0
        public void StackSize()
        {
            // Generate an array crafted to invoke the bug in the Java TimSort before it was fixed.
            // Before the fix an index-out-of-range exception would be thrown.
            int[] arr = GenData();
            TimSort <int> .Sort(arr);

            // While we're here, check the sort actually worked.
            Assert.IsTrue(SortUtils.IsSortedAscending(arr));
        }
Пример #13
0
        private void LongRandomArraysInner(int len, IRandomSource rng)
        {
            // Create random array.
            int[] keys = CreateRandomArray(len, rng);

            // Sort array.
            TimSort <int> .Sort(keys);

            // Check array is sorted.
            Assert.IsTrue(SortUtils.IsSortedAscending(keys));
        }
Пример #14
0
        public void Sort_ShortArray()
        {
            int[] keys = new int[] { 5, 8, 2, 16, 32, 12, 7 };
            int[] vals = new int[] { 0, 1, 2, 3, 4, 5, 6 };
            int[] wals = new int[] { 6, 5, 4, 3, 2, 1, 0 };

            TimSort <int, int, int> .Sort(keys, vals, wals);

            Assert.Equal(new int[] { 2, 5, 7, 8, 12, 16, 32 }, keys);
            Assert.Equal(new int[] { 2, 0, 6, 1, 5, 3, 4 }, vals);
            Assert.Equal(new int[] { 4, 6, 0, 5, 1, 3, 2 }, wals);
        }
        /// <summary>
        /// This Breeding Pair Selector returns pairings where the even numbers alternate between the two fittest parents, while the odd numbers descend sequentially through the remaining fittest entities.
        /// </summary>
        /// <param name="pPopulation"></param>
        /// <returns>List of GeneticEntity</returns>
        public List <T> SelectPairs <T>(List <T> pPopulation) where T : GeneticEntity
        {
            //Create a new list to return
            List <T> pairGrouping = new List <T>();

            T[] popArray = pPopulation.ToArray();
            //Sort by fittest
            TimSort <T> .sort(popArray, new GeneticEntityComparable());

            //0A     1B
            //2A     3C
            //4B     5D
            //6A     7E
            //8B     9F


            //Initial princely load
            pairGrouping.Add(popArray[0]);
            pairGrouping.Add(popArray[1]);

            int princelyOffset = 2;

            //The first of the remaining population after the princes
            int index = princelyOffset + 1;

            int lengthOfPairing = (popArray.Length - princelyOffset) * 2;

            for (int i = princelyOffset; i < lengthOfPairing; i++)
            {
                //If even
                if (i % 2 == 0)
                {
                    index = 0; //Prince A

                    //If every second even
                    if (i % 4 == 0)
                    {
                        index = 1; //Prince B
                    }
                }
                else
                {
                    index++;
                }

                pairGrouping.Add(popArray[index]);
            }


            return(pairGrouping);
        }
Пример #16
0
        public void Test(int[] data)
        {
            // Arrange
            int[] data2 = new int[data.Length];
            Array.Copy(data, data2, data.Length);
            Array.Sort(data2);
            var sorter = new TimSort <int>();

            // Act
            sorter.Sort(data);

            // Assert
            CollectionAssert.AreEqual(data, data2);
        }
Пример #17
0
        private void Sort_LongRandomArrays_Inner(int len, IRandomSource rng)
        {
            // Create random array.
            int[] keys = CreateRandomArray(len, rng);

            // For the vals array, use a copy of the keys, but add a large constant so that we
            // can be sure keys weren't just copied by accident into vals.
            const int offsetv = 1_000_000;

            int[] vals = (int[])keys.Clone();
            for (int i = 0; i < vals.Length; i++)
            {
                vals[i] += offsetv;
            }

            // Repeat the same procedure for wals.
            const int offsetw = 10_000_000;

            int[] wals = (int[])keys.Clone();
            for (int i = 0; i < wals.Length; i++)
            {
                wals[i] += offsetw;
            }

            // Sort array.
            TimSort <int, int, int> .Sort(keys, vals, wals);

            // Check array is sorted.
            Assert.True(SortUtils.IsSortedAscending <int>(keys));

            // Checks vals.
            for (int i = 0; i < keys.Length; i++)
            {
                Assert.Equal(keys[i] + offsetv, vals[i]);
            }

            // Checks wals.
            for (int i = 0; i < keys.Length; i++)
            {
                Assert.Equal(keys[i] + offsetw, wals[i]);
            }
        }
Пример #18
0
        /// <summary>
        /// This Breeding Pair Selector returns pairings where the even numbers are always the fittest entity of the entire pool (the alpha) while odd numbers contain the next most fit entity descending sequentially. The first pairing contains two copies of the alpha and will therefore result in an asexually reproduced offspring.
        /// </summary>
        /// <param name="pPopulation"></param>
        /// <returns>List of GeneticEntity</returns>
        public List <T> SelectPairs <T>(List <T> pPopulation) where T : GeneticEntity
        {
            //Create a new list to return
            List <T> pairGrouping = new List <T>();

            T[] popArray = pPopulation.ToArray();
            //Sort by fittest
            TimSort <T> .sort(popArray, new GeneticEntityComparable());

            //On even numbers we will always choose the fittest entity. On odd numbers we will chose
            //the next fittest entity in the pool
            for (int i = 0; i < popArray.Length; i++)
            {
                int index = i % 2 == 0 ?
                            0 :
                            i / 2;

                pairGrouping.Add(popArray[index]);
            }
            return(pairGrouping);
        }
Пример #19
0
        private static void RunTest_TimSort_Natural(
            int length, int loopsPerRun)
        {
            // Alloc a re-usable working array for timsort.
            int[] workArr = new int[50000];

            // Create wrapper for timsort that provides the working array.
            void timsort(int[] arr)
            {
                TimSort <int> .Sort(arr, 0, arr.Length, workArr);
            }

            var benchmark = new ArraySortPerfTest(
                ArraySortPerfTestUtils.InitNatural,
                timsort,
                length,
                loopsPerRun);

            double msPerSort = benchmark.Run();

            Console.WriteLine($"TimSort<int>.Sort [Natural]:\t{msPerSort} ms / sort");
        }
Пример #20
0
        /// <summary>
        /// This Breeding Pair Selector returns pairings where the even numbers are the given mating pool's fittest and the odd are its least fit. This grouping is used to pair the fittest entities with the least fit together.
        /// </summary>
        /// <param name="pPopulation"></param>
        /// <returns>List of GeneticEntity</returns>
        public List <T> SelectPairs <T>(List <T> pPopulation) where T : GeneticEntity
        {
            //Create a new list to return
            List <T> pairGrouping = new List <T>();

            T[] popArray = pPopulation.ToArray();
            //Sort our pool by entity fitness
            TimSort <T> .sort(popArray, new GeneticEntityComparable());

            //Loop through the pool
            for (int i = 0; i < popArray.Length; i++)
            {
                //Our chosen index will be i / 2 (the fittest) on even numbers while the least fittest
                //on odd numbers, using list.count - 1 (accounting for zero-indexing) minus
                //the loop's iteration
                int index = i % 2 == 0 ?
                            (i / 2) :
                            (popArray.Length - 1) - i;

                pairGrouping.Add(popArray[index]);
            }
            return(pairGrouping);
        }
Пример #21
0
        static void Main(string[] args)
        {
            int[] arr = new int[10000];
            Random rnd = new Random();
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = rnd.Next(10000);
            }
            ISort<int> s = new BubbleSort<int>();
            DateTime dt = DateTime.Now;
            arr = s.Sorting(arr);
            Console.WriteLine("Time for BubbleSort is {0}.", DateTime.Now - dt);

            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = rnd.Next(10000);
            }
            dt = DateTime.Now;
            s = new CocktailSort<int>();
            arr = s.Sorting(arr);
            Console.WriteLine("Time for CocktailSort is {0}.", DateTime.Now - dt);

            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = rnd.Next(10000);
            }
            dt = DateTime.Now;
            s = new EvenOddSort<int>();
            arr = s.Sorting(arr);
            Console.WriteLine("Time for EvenOddSort is {0}.", DateTime.Now - dt);

            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = rnd.Next(10000);
            }
            dt = DateTime.Now;
            s = new CombSort<int>();
            arr = s.Sorting(arr);
            Console.WriteLine("Time for CombSort is {0}.", DateTime.Now - dt);

            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = rnd.Next(10000);
            }
            dt = DateTime.Now;
            s = new GnomeSort<int>();
            arr = s.Sorting(arr);
            Console.WriteLine("Time for GnomeSort is {0}.", DateTime.Now - dt);

            arr = new int[10000];
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = rnd.Next(10000);
            }
            dt = DateTime.Now;
            s = new InsertionSort<int>();
            arr = s.Sorting(arr);
            Console.WriteLine("Time for InsertionSort is {0}.", DateTime.Now - dt);

            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = rnd.Next(10000);
            }
            dt = DateTime.Now;
            s = new BinaryInsertionSort<int>();
            arr = s.Sorting(arr);
            Console.WriteLine("Time for BinaryInsertionSort is {0}.", DateTime.Now - dt);

            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = rnd.Next(10000);
            }
            dt = DateTime.Now;
            s = new ShellSort<int>();
            arr = s.Sorting(arr);
            Console.WriteLine("Time for ShellSort is {0}.", DateTime.Now - dt);

            arr = new int[1000000];
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = rnd.Next(1000000);
            }
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = rnd.Next(10000);
            }
            dt = DateTime.Now;
            s = new HeapSort<int>();
            arr = s.Sorting(arr);
            Console.WriteLine("Time for HeapSort is {0}.", DateTime.Now - dt);
            int ddd = 0;
            for (int i = 0; i < arr.Length - 2; i++)
            {
                //Console.Write(arr[i] + " ");
                if (arr[i] > arr[i + 1]) //Console.WriteLine("Fatal ERROR!!!");
                    ddd++;
            }
            Console.WriteLine("Error count: {0}", ddd);

            dt = DateTime.Now;
            s = new MergeSort<int>();
            arr = s.Sorting(arr);
            Console.WriteLine("Time for MergeSort is {0}.", DateTime.Now - dt);

            //StreamWriter sw = new StreamWriter("C:/Users/suvorovi/1.txt");
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = rnd.Next(1000000);
                //sw.Write(arr[i] + " ");
            }
            //sw.WriteLine("");
            dt = DateTime.Now;
            s = new QuickSort<int>();
            arr = s.Sorting(arr);
            Console.WriteLine("Time for QuickSort is {0}.", DateTime.Now - dt);
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = rnd.Next(1000000);
                //sw.Write(arr[i] + " ");
            }
            //sw.WriteLine("");
            dt = DateTime.Now;
            s = new TimSort<int>();
            arr = s.Sorting(arr);
            Console.WriteLine("Time for TimSort is {0}.", DateTime.Now - dt);
            ddd = 0;
            for (int i = 0; i < arr.Length - 2; i++)
            {
                //Console.Write(arr[i] + " ");
                if (arr[i] > arr[i + 1]) //Console.WriteLine("Fatal ERROR!!!");
                    ddd++;
            }
            Console.WriteLine("Error count: {0}", ddd);
            Console.ReadLine();
            //sw.Close();
        }
Пример #22
0
 public void TimSort()
 {
     TimSort <int, int, int> .Sort(_keys, _values, _values2);
 }
Пример #23
0
 public void TimSort_NaturallyOrderedKeys()
 {
     TimSort <int, int, int> .Sort(_keys, _values, _values2);
 }
Пример #24
0
    //Subscribed to PlotStart, which is queued in UIReflect after UI updates (which is queued StartEvolve)
    private void EvolvePopulation(object sender, EventArgs e)
    {
        TimeLogger.LogStart();
        float averageFitness = 0.0f;

        List <Bed> evolvedBeds = new List <Bed>();

        //Actual Evolve process
        for (int g = 0; g < givenIterations; g++)
        {
            //New beds get inited from rand conditions for the first gen
            //Should ideally ahve already been done from Start -> ResetPopulation, just a safety measure
            if (!initialised)
            {
                newBeds = CreateBeds();
            }

            //The previous List gets emptied. This data is now stored in newBeds after the last generation
            if (initialised)
            {
            }

            /*for (int i = 0; i < beds.Count; i++)
             * {
             *  beds[i].ComputeFitness();
             * }*/
            if (evolvedBeds == null)
            {
                //Debug.Log("Evolved null");
            }
            if (newBeds == null)
            {
                //Debug.Log("new beds null");
            }

            //Use the GA to evolve our data
            evolvedBeds = GeneticEvolution.Evolve(newBeds, newBeds.Count, testbench.GetUsedMatingPoolSelector(),
                                                  testbench.GetUsedBreedingPairSelector(),
                                                  testbench.GetUsedCrossoverOperator(),
                                                  testbench.GetUsedMutator());

            for (int i = 0; i < evolvedBeds.Count; i++)
            {
                evolvedBeds[i].LoadGardenAndPatches(this, patches);
            }
            generationNumber++;

            //Debug.Log("Unsorted List " + beds[0].Fitness);
            Bed[] bedArray = evolvedBeds.ToArray();
            TimSort <Bed> .sort(bedArray, new GeneticEntityComparable());

            /* for (int i = 0; i < bedArray.Length; i++)
             * {
             *   Debug.Log("Sorted post-gen i: " + i + " Fitness: " + bedArray[i].Fitness);
             * }*/
            //Debug.Log("Top of Array: " + bedArray[0].Fitness);
            evolvedBeds = new List <Bed>(bedArray);

            //Trimming the solutions
            //Debug.Log("Evolved Beds pre-trim - size: " + evolvedBeds.Count);

            //Certain Pair Selectors create larger numbers of solutions than the intial set of parents.
            //In this case, we require as many solutions (beds) as we put in and therefore remove the excess
            //after they've been fitness sorted
            if (evolvedBeds.Count > numberOfBeds)
            {
                evolvedBeds.RemoveRange(numberOfBeds - 1, (evolvedBeds.Count - numberOfBeds));
            }
            //Debug.Log("Evolved Beds post-trim - size: " + evolvedBeds.Count);


            averageFitness = 0.0f;
            for (int i = 0; i < evolvedBeds.Count; i++)
            {
                averageFitness += evolvedBeds[i].Fitness;
                // Debug.Log("Beds [" + i + "]:" + beds[i].Fitness);
            }
            averageFitness /= evolvedBeds.Count;

            //Clear out the starting beds
            newBeds.Clear();

            //Save the evolved beds into a new starting List to be used for the next generation
            for (int i = 0; i < evolvedBeds.Count; i++)
            {
                newBeds.Add(evolvedBeds[i]);
            }

            //Clear out the evolved one
            evolvedBeds.Clear();

            //Debug.Log("End of gen loop - eb size: " + evolvedBeds.Count + " | nb: " + newBeds.Count);
        }


        TimeLogger.LogEnd();
        EventQueue.QueueEvent(EventQueue.EventType.Plot_End, this, new TimeArgs(Time.realtimeSinceStartup));
        //We use newBeds not evolvedBeds here since at the end of the gen, new holds the next (or last) generation's data
        //and evolved is already cleared for the next gen
        EventQueue.QueueEvent(EventQueue.EventType.BroadcastGeneration, this, new GenerationArgs <Bed>(newBeds, newBeds[0].Fitness, averageFitness, generationNumber, testingBase));
    }
Пример #25
0
 public void Sort()
 {
     TimSort <XPathItem> .sort(_items, 0, _size, new XPathComparer());
 }
        /// <summary>
        /// This Breeding Pair Selector returns pairings where the first half of the even numbers contains the most fit parent, while the latter half contains the second most fit parent. The odd numbers descend sequentially through the remaining fittest entities.
        /// </summary>
        /// <param name="pPopulation"></param>
        /// <returns>List of GeneticEntity</returns>
        public List <T> SelectPairs <T>(List <T> pPopulation) where T : GeneticEntity
        {
            //Create a new list to return
            List <T> pairGrouping = new List <T>();

            T[] popArray = pPopulation.ToArray();

            //Sort by fittest
            TimSort <T> .sort(popArray, new GeneticEntityComparable());

            //0A     1C
            //2A     3D
            //4A     5E
            //6B     7F
            //8B     9G
            //10B    11H

            //Debug.Log("pairGrouping size is: " + pairGrouping.Count);
            //Partner index is for the non-prince partner of the breeding pair
            int partnerIndex = princeOffset;

            //Prince index controls which prince is plugged in
            int princeIndex = 0;

            //Index is what gets plugged to the list
            int index = 0;

            //The pairing should exclude the two princes, and be equal to the remaining partners x2
            //(since each partner needs the following slot to be filled by a prince)
            int lengthOfPairing = (popArray.Length - partnerIndex) * 2;

            //Debug.Log("poparray: " + popArray.Length);
            for (int i = 0; i < lengthOfPairing; i++)
            {
                //int index = i + 2;

                //To avoid duplication, we assume partner status and negate and switch to prince if need be
                index = partnerIndex;

                //If odd
                if (i % 1 == 0)
                {
                    //First half of pool
                    if (i < popArray.Length / 2)
                    {
                        princeIndex = 0; //Prince A
                    }
                    //Latter half of pool
                    else
                    {
                        princeIndex = 1; //Prince B
                    }
                    index = princeIndex;
                }
                else
                {
                    partnerIndex++;
                }



                //Debug.Log("i is: " + i + " while index is: " + index);
                //There is an unfixed OutOfRangeException here
                pairGrouping.Add(popArray[index]);
            }


            return(pairGrouping);
        }