예제 #1
0
        public int Spawn(LabeledVector <L> lvector, DistanceDelegate measure, ParallelStrategy parallelStrategy, bool spawnUsingLDA)
        {
            int nSpawnCount = 0;

            if (this.DoesEncloseVector(lvector, measure))
            {
                if (parallelStrategy == ParallelStrategy.Multithreaded)
                {
                    List <Task> lstSpawnThreads = new List <Task>();
                    foreach (SphereEx <L> child in this.Children)
                    {
                        lstSpawnThreads.Add(Task.Factory.StartNew(c =>
                        {
                            nSpawnCount += ((SphereEx <L>)c).Spawn(lvector, measure, ParallelStrategy.SingleThreaded, spawnUsingLDA);
                        }, child, TaskCreationOptions.LongRunning));
                    }

                    Task.WaitAll(lstSpawnThreads.ToArray());
                }
                else
                {
                    foreach (SphereEx <L> child in this.Children)
                    {
                        nSpawnCount += child.Spawn(lvector, measure, ParallelStrategy.SingleThreaded, spawnUsingLDA);
                    }
                }

                if (!spawnUsingLDA)
                {
                    #region Regular Spawn

                    if (!this.Label.Equals(lvector.Label) && !Vector.EqualsEx(this, lvector) && !this.DoesAtLeastOneChildEncloseVector(lvector, measure))
                    {
                        SphereEx <L> child = new SphereEx <L>(this.Radius - measure(this, lvector), lvector);
                        child.LDAVectors.Add(child.Label, new List <KeyValuePair <int, LabeledVector <L> > >()
                        {
                            new KeyValuePair <int, LabeledVector <L> >(0, lvector)
                        });
                        this.AddChild(child);
                        nSpawnCount++;
                    }

                    #endregion
                }
                else
                {
                    #region LDA Spawn

                    // Note that LDA Spawn doesn't work with SquaredEuclideanDistance.  I may -- in the future -- do an additional check to see if the vector is contained by the hypersphere with SquaredEuclideanDistance and EuclideanDistance.  If so, this will work.  Until then, I'll leave it as is.
                    if (this.Children.Any())
                    {
                        // Next if-statement a duplicate of the region "Regular Spawn"
                        // Remember, LDA is only applied at nodes with no children (leaf)
                        if (!this.Label.Equals(lvector.Label) && !Vector.EqualsEx(this, lvector) && !this.DoesAtLeastOneChildEncloseVector(lvector, measure))
                        {
                            SphereEx <L> child = new SphereEx <L>(this.Radius - measure(this, lvector), lvector);
                            child.LDAVectors.Add(child.Label, new List <KeyValuePair <int, LabeledVector <L> > >()
                            {
                                new KeyValuePair <int, LabeledVector <L> >(0, lvector)
                            });
                            this.AddChild(child);
                            nSpawnCount++;
                        }
                    }
                    else
                    {
                        bool bContains = false;

                        List <KeyValuePair <int, LabeledVector <L> > > lst;
                        if (!this.LDAVectors.TryGetValue(lvector.Label, out lst))
                        {
                            this.LDAVectors.Add(lvector.Label, (lst = new List <KeyValuePair <int, LabeledVector <L> > >()));
                        }
                        else
                        {
                            bContains = lst.Any(kvp => Vector.EqualsEx(kvp.Value, lvector));
                        }

                        if (!bContains)
                        {
                            lst.Add(new KeyValuePair <int, LabeledVector <L> >(this.LDAVectors.Sum(kvp => kvp.Value.Count), lvector));

                            if (this.LDAVectors.Keys.Count == 2)
                            {
                                #region If the sphere contains exactly 2 classes, do the following...

                                bool bIsSeparable = false;
                                DiscriminantEx <L> discriminant = null;
                                try
                                {
                                    bIsSeparable = LDAEx.IsCompletelySeparatedWithDiscriminant(this.LDAVectors.ElementAt(0).Value.Select(kvp => kvp.Value).ToList(), this.LDAVectors.ElementAt(1).Value.Select(kvp => kvp.Value).ToList(), out discriminant);
                                }
                                catch
                                {
                                    // Just consume, leaving bIsSeparable = false
                                }

                                if (!bIsSeparable)
                                {
                                    bool spawnedAtLeastOnce            = false;
                                    List <LabeledVector <L> > lstCache = this.LDAVectors.SelectMany(kvp => kvp.Value).OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value).ToList();

                                    this.LDAVectors.Clear();
                                    this.DiscriminantEx = null;

                                    foreach (LabeledVector <L> v in lstCache)
                                    {
                                        if (!spawnedAtLeastOnce)
                                        {
                                            int count = this.Spawn(v, measure, ParallelStrategy.SingleThreaded, false);
                                            nSpawnCount       += count;
                                            spawnedAtLeastOnce = count > 0;
                                        }
                                        else
                                        {
                                            nSpawnCount += this.Spawn(v, measure, ParallelStrategy.SingleThreaded, true);
                                        }
                                    }
                                }
                                else
                                {
                                    if (discriminant != null)
                                    {
                                        this.DiscriminantEx = discriminant;
                                    }
                                }

                                #endregion
                            }
                            else if (this.LDAVectors.Keys.Count > 2)
                            {
                                #region If the sphere contains 3 or more classes, do the following...

                                bool spawnedAtLeastOnce            = false;
                                List <LabeledVector <L> > lstCache = this.LDAVectors.SelectMany(kvp => kvp.Value).OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value).ToList();

                                this.LDAVectors.Clear();
                                this.DiscriminantEx = null;

                                foreach (LabeledVector <L> v in lstCache)
                                {
                                    if (!spawnedAtLeastOnce)
                                    {
                                        int count = this.Spawn(v, measure, ParallelStrategy.SingleThreaded, false);
                                        nSpawnCount       += count;
                                        spawnedAtLeastOnce = count > 0;
                                    }
                                    else
                                    {
                                        nSpawnCount += this.Spawn(v, measure, ParallelStrategy.SingleThreaded, true);
                                    }
                                }

                                #endregion
                            }
                            // Note: If this.LDAVectors.Keys.Count == 1, don't do anything additional.
                        }
                    }

                    #endregion
                }
            }

            return(nSpawnCount);
        }
예제 #2
0
        public int Spawn(LabeledVector <L> lvector, DistanceDelegate measure, ParallelStrategy parallelStrategy, bool spawnUsingLDA)
        {
            int nSpawnCount = 0;

            if (this.DoesEncloseVector(lvector, measure))
            {
                if (parallelStrategy == ParallelStrategy.Multithreaded)
                {
                    List <Task> lstSpawnThreads = new List <Task>();
                    foreach (SphereEx <L> child in this.Children)
                    {
                        lstSpawnThreads.Add(Task.Factory.StartNew(c =>
                        {
                            nSpawnCount += ((SphereEx <L>)c).Spawn(lvector, measure, ParallelStrategy.SingleThreaded, spawnUsingLDA);
                        }, child, TaskCreationOptions.LongRunning));
                    }

                    Task.WaitAll(lstSpawnThreads.ToArray());
                }
                else
                {
                    foreach (SphereEx <L> child in this.Children)
                    {
                        nSpawnCount += child.Spawn(lvector, measure, ParallelStrategy.SingleThreaded, spawnUsingLDA);
                    }
                }

                if (!spawnUsingLDA)
                {
                    #region Regular Spawn

                    if (!this.Label.Equals(lvector.Label) && !Vector.EqualsEx(this, lvector) && !this.DoesAtLeastOneChildEncloseVector(lvector, measure))
                    {
                        this.AddChild(new SphereEx <L>(this.Radius - measure(this, lvector), lvector));
                        nSpawnCount++;
                    }

                    #endregion
                }
                else
                {
                    #region LDA Spawn

                    if (!this.DoesAtLeastOneChildEncloseVector(lvector, measure))   // Don't care about label as well as location of lvector
                    {
                        bool bContains = false;

                        List <LabeledVector <L> > lst;
                        if (!this.LDAVectors.TryGetValue(lvector.Label, out lst))
                        {
                            this.LDAVectors.Add(lvector.Label, (lst = new List <LabeledVector <L> >()));
                        }
                        else
                        {
                            bContains = lst.Any(v => Vector.EqualsEx(v, lvector));
                        }

                        if (!bContains)
                        {
                            lst.Add(lvector);

                            if (this.LDAVectors.Keys.Count == 2 && !this.Children.Any())
                            {
                                #region If the sphere contains exactly 2 classes, do the following...
                                // 1.  Create another discriminant
                                // 2.  If the discrimant CANNOT separate the classes, do the following...
                                // 2a.    Remove the lvector from the list it was just added to
                                // 2b.    Create new children from the classes
                                // 2c.    Try to spawn the presented LVector in the NEW children
                                // 2d.    Clear the dictionary, LDAVectors
                                // 2e.    If you can't spawn WITHIN the NEW children, add the vector to the this.LDAVectors
                                // 3.  Else (If the discrimant CAN separate the classes), do nothing but assign the property.

                                bool bIsSeparable = false;
                                DiscriminantEx <L> discriminant = null;
                                try
                                {
                                    //bIsSeparable = LDA.IsCompletelySeparatedWithDiscriminant(this.LDAVectors.ElementAt(0).Value, this.LDAVectors.ElementAt(1).Value, this, out discriminant);

                                    bIsSeparable = LDAEx.IsCompletelySeparatedWithDiscriminant(this.LDAVectors.ElementAt(0).Value, this.LDAVectors.ElementAt(1).Value, out discriminant);
                                }
                                catch
                                {
                                    // Just consume, leaving bIsSeparable = false
                                }

                                if (!bIsSeparable)
                                {
                                    lst.RemoveAt(lst.Count - 1);    // Faster than .Remove() as I am not linearly searching

                                    List <SphereEx <L> > lstNewChildren = new List <SphereEx <L> >();
                                    foreach (KeyValuePair <L, List <LabeledVector <L> > > kvp in this.LDAVectors)
                                    {
                                        if (kvp.Value.Any() && !kvp.Key.Equals(this.Label))
                                        {
                                            //Vector vectorCentroid = Vector.Centroid(kvp.Value);

                                            //if (!Vector.EqualsEx(this, vectorCentroid))
                                            //{
                                            //    SphereEx<L> child = new SphereEx<L>(this.Radius - measure(this, vectorCentroid), kvp.Key, (IVector)vectorCentroid);

                                            //    this.AddChild(child);
                                            //    lstNewChildren.Add(child);
                                            //    nSpawnCount++;
                                            //}
                                        }
                                    }

                                    //bool hasSpawned = false;
                                    //foreach (SphereEx<L> child in lstNewChildren)
                                    //{
                                    //    if (child.DoesEncloseVector(lvector, measure))
                                    //    {
                                    //        nSpawnCount += child.Spawn(lvector, measure, ParallelStrategy.SingleThreaded, spawnUsingLDA);
                                    //        hasSpawned = true;
                                    //    }
                                    //}

                                    this.LDAVectors.Clear();

                                    //if (!hasSpawned)
                                    //{
                                    //    this.LDAVectors.Add(lvector.Label, new List<LabeledVector<L>>() { lvector });
                                    //}
                                }
                                else
                                {
                                    this.DiscriminantEx = discriminant;
                                }

                                #endregion
                            }
                            else if (this.LDAVectors.Keys.Count > 2)
                            {
                                #region If the sphere contains 3 or more classes, do the following...
                                // 1.  Create children from the OLDER label-sets
                                // 2.  Try to spawn the presented LVector IN the NEW children just created
                                // 3.  Clear the dictionary, LDAVectors
                                // 4.  If you can't spawn WITHIN the NEW children, add the vector to this.LDAVectors

                                List <SphereEx <L> > lstNewChildren = new List <SphereEx <L> >();

                                foreach (KeyValuePair <L, List <LabeledVector <L> > > kvp in this.LDAVectors)
                                {
                                    if (!kvp.Key.Equals(lvector.Label))
                                    {
                                        Vector vectorCentroid = Vector.Centroid(kvp.Value);

                                        if (!Vector.EqualsEx(this, vectorCentroid))
                                        {
                                            SphereEx <L> child = new SphereEx <L>(this.Radius - measure(this, vectorCentroid), kvp.Key, (IVector)vectorCentroid);

                                            this.AddChild(child);
                                            lstNewChildren.Add(child);
                                            nSpawnCount++;
                                        }
                                    }
                                }

                                //bool hasSpawned = false;
                                //foreach (SphereEx<L> child in lstNewChildren)
                                //{
                                //    if (child.DoesEncloseVector(lvector, measure))
                                //    {
                                //        nSpawnCount += child.Spawn(lvector, measure, ParallelStrategy.SingleThreaded, spawnUsingLDA);
                                //        hasSpawned = true;
                                //    }
                                //}

                                this.LDAVectors.Clear();

                                //if (!hasSpawned)
                                //{
                                //    this.LDAVectors.Add(lvector.Label, new List<LabeledVector<L>>() { lvector });
                                //}

                                #endregion
                            }
                            // Note: If this.LDAVectors.Keys.Count == 1, don't do anything additional.
                        }
                    }

                    #endregion
                }
            }

            return(nSpawnCount);
        }
예제 #3
0
파일: Program.cs 프로젝트: sbreed/STRHC
        static void Main(string[] args)
        {
            ParallelStrategy strategy = ParallelStrategy.SingleThreaded;
            bool             bIsLDA   = true;

            RHCLib.DistanceDelegate measure = RHCLib.Vector.EuclideanDistance;

            int nQueuePartitions;        // = 2;
            int nSlotsPerQueuePartition; // = 40;
            // If using the example, the total queue is 80

            string strFile;
            bool   bIsSTRHC1; // STRHC1 = Small dataset (40 gestures), !STRHC1 = Large dataset (300 gestures)

            #region Parameters

            if (args.Length != 5)
            {
                System.Console.WriteLine("Syntax: STRHC.EXE <Queue Partitions> <Slots Per Partition> <T|F IsLDA> <T|F IsSingledThreaded> <1 = STRHC1 (40 gestures) | 2 = STRHC2 (300 gestures)>");
                return;
            }
            else
            {
                bool singleThreaded;
                int  dataset;
                if (!int.TryParse(args[0], out nQueuePartitions) || !int.TryParse(args[1], out nSlotsPerQueuePartition) || !bool.TryParse(args[2], out bIsLDA) || !bool.TryParse(args[3], out singleThreaded) || !int.TryParse(args[4], out dataset) || !(new int[] { 1, 2 }.Contains(dataset)))
                {
                    System.Console.WriteLine("Syntax: STRHC.EXE <Queue Partitions> <Slots Per Partition> <T|F IsLDA> <T|F IsSingledThreaded> <1 = STRHC1 (40 gestures) | 2 = STRHC2 (300 gestures)>");
                    return;
                }

                switch (dataset)
                {
                case 1:
                    bIsSTRHC1 = true;
                    strFile   = @".\Data1.dat";
                    break;

                case 2:
                    bIsSTRHC1 = false;
                    strFile   = @".\Data.dat";
                    break;

                default:
                    throw new NotImplementedException();
                }

                strategy = singleThreaded ? ParallelStrategy.SingleThreaded : ParallelStrategy.Multithreaded;
            }

            #endregion

            System.Diagnostics.Process.GetCurrentProcess().PriorityClass = System.Diagnostics.ProcessPriorityClass.High;

            using (System.IO.StreamWriter sw = new System.IO.StreamWriter(string.Format(@".\{0:yyyy-MM-ddTHHmmss} {1} {2}x{3} {4} {5}", DateTime.Now, bIsSTRHC1 ? "STRHC1" : "STRHC2", nQueuePartitions, nSlotsPerQueuePartition, bIsLDA ? "LDA" : "NoLDA", measure == Vector.SquaredEuclideanDistance ? "SqEuc" : "Euc"), false, Encoding.UTF8))
            {
                Dictionary <int, Tuple <Dictionary <string, List <List <double[]> > >, Dictionary <string, List <List <double[]> > > > > dict;

                using (System.IO.FileStream fs = new System.IO.FileStream(strFile, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    dict = bf.Deserialize(fs) as Dictionary <int, Tuple <Dictionary <string, List <List <double[]> > >, Dictionary <string, List <List <double[]> > > > >;
                }

                #region Convert the dictGestures into RHCLib.LabeledVectors

                Dictionary <int, Tuple <List <RHCLib.LabeledVector <string>[]>, List <RHCLib.LabeledVector <string>[]> > > dictGestures = new Dictionary <int, Tuple <List <LabeledVector <string>[]>, List <LabeledVector <string>[]> > >();
                foreach (KeyValuePair <int, Tuple <Dictionary <string, List <List <double[]> > >, Dictionary <string, List <List <double[]> > > > > kvp in dict)
                {
                    List <LabeledVector <string>[]> lstTrain = new List <LabeledVector <string>[]>();
                    foreach (KeyValuePair <string, List <List <double[]> > > kvpTrain in kvp.Value.Item1)
                    {
                        foreach (List <double[]> gesture in kvpTrain.Value)
                        {
                            List <LabeledVector <string> > lst = new List <LabeledVector <string> >();
                            foreach (double[] frame in gesture)
                            {
                                lst.Add(new LabeledVector <string>(kvpTrain.Key, frame));
                            }
                            lstTrain.Add(lst.ToArray());
                        }
                    }

                    List <LabeledVector <string>[]> lstTest = new List <LabeledVector <string>[]>();
                    foreach (KeyValuePair <string, List <List <double[]> > > kvpTest in kvp.Value.Item2)
                    {
                        foreach (List <double[]> gesture in kvpTest.Value)
                        {
                            List <LabeledVector <string> > lst = new List <LabeledVector <string> >();
                            foreach (double[] frame in gesture)
                            {
                                lst.Add(new LabeledVector <string>(kvpTest.Key, frame));
                            }
                            lstTest.Add(lst.ToArray());
                        }
                    }

                    dictGestures.Add(kvp.Key, new Tuple <List <LabeledVector <string>[]>, List <LabeledVector <string>[]> >(lstTrain, lstTest));
                }

                #endregion

                IList <string> classes     = dict.Values.First().Item1.Keys.ToList();
                int            nClassCount = classes.Count();

                int nFeatureSpaceDimensionality = dictGestures.Values.First().Item1.First().First().Rank + (nQueuePartitions * nClassCount);

                foreach (KeyValuePair <int, Tuple <List <RHCLib.LabeledVector <string>[]>, List <RHCLib.LabeledVector <string>[]> > > kvp in dictGestures)
                {
                    SphereEx <string> sphere = new SphereEx <string>(Sphere <string> .CreateUnitSphere(measure, nFeatureSpaceDimensionality, string.Empty));

                    int nEpoch = 1;
                    int nSpawnCount;
                    RHCLib.LabeledVector <string> lvectorAug;

                    Program.WriteStream(sw, string.Format("Fold: {0}", kvp.Key));

                    System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
                    watch.Start();

                    #region Train

                    do
                    {
                        nSpawnCount = 0;

                        foreach (RHCLib.LabeledVector <string>[] gesture in kvp.Value.Item1)
                        {
                            double[][] queue = Program.CreateEmptyQueue(nQueuePartitions, nSlotsPerQueuePartition, nClassCount);

                            foreach (RHCLib.LabeledVector <string> frame in gesture)
                            {
                                lvectorAug = Program.CreateAugmentedVector(frame, queue, nQueuePartitions, nSlotsPerQueuePartition);

                                double[] biases = sphere.CalculateBiases(lvectorAug, measure, classes);

                                nSpawnCount += sphere.Spawn(lvectorAug, measure, strategy, bIsLDA);

                                Program.AdvanceQueue(queue, biases);
                            }
                        }

                        Program.WriteStream(sw, string.Format("  Epoch:\t{0}\t{1}", nEpoch++, nSpawnCount));
                    } while (nSpawnCount > 0);

                    watch.Stop();

                    Program.WriteStream(sw, string.Format("TOTAL TIME [ms] for Fold {0}: {1}", kvp.Key, watch.ElapsedMilliseconds.ToString()));
                    Program.WriteStream(sw, string.Format("Sphere Count: {0}", sphere.SphereCount));
                    Program.WriteStream(sw, string.Format("Tree Height: {0}", sphere.Height));
                    Program.WriteStream(sw, string.Format("Epoch Count: {0}", nEpoch - 1));

                    #endregion

                    #region Test

                    Sphere <string> sphereWinner = null;

                    int nSphereCorrect   = 0;
                    int nSphereIncorrect = 0;
                    int nQueueCorrect    = 0;
                    int nQueueIncorrect  = 0;

                    foreach (RHCLib.LabeledVector <string>[] gesture in kvp.Value.Item2)
                    {
                        #region Create Empty Queue

                        double[][] queue = new double[nQueuePartitions * nSlotsPerQueuePartition][];
                        for (int i = 0; i < queue.Length; i++)
                        {
                            queue[i] = new double[nClassCount];
                        }

                        #endregion

                        watch.Reset();
                        watch.Start();

                        foreach (RHCLib.LabeledVector <string> frame in gesture)
                        {
                            lvectorAug = Program.CreateAugmentedVector(frame, queue, nQueuePartitions, nSlotsPerQueuePartition);

                            sphereWinner = sphere.Recognize(lvectorAug, measure, strategy);

                            double[] rgBiases = sphere.CalculateBiases(lvectorAug, measure, classes);

                            Program.AdvanceQueue(queue, rgBiases);
                        }
                        watch.Stop();

                        Program.WriteStream(sw, string.Format("[{0} fold] Time to recognize [in ms]: {1}", kvp.Key, watch.ElapsedMilliseconds));

                        #region Sphere Winner

                        Program.WriteStream(sw, string.Format("Actual: {0}\t\tSphere Recognized: {1}", gesture.First().Label, sphereWinner.Label));
                        if (sphereWinner.Label == gesture.First().Label)
                        {
                            nSphereCorrect++;
                        }
                        else
                        {
                            nSphereIncorrect++;
                        }

                        #endregion

                        #region Queue Winner

                        Dictionary <string, double> dictWinner = new Dictionary <string, double>();
                        foreach (string strClass in classes)
                        {
                            dictWinner.Add(strClass, 0.0);
                        }

                        // Quick and dirty
                        Dictionary <string, double> dictQueueBreakout = new Dictionary <string, double>();
                        foreach (string strClass in classes)
                        {
                            dictQueueBreakout.Add(strClass, 0.0);
                        }
                        for (int i = 0; i < queue.Length; i++)
                        {
                            for (int j = 0; j < queue[i].Length; j++)
                            {
                                dictQueueBreakout[classes.ElementAt(j)] += queue[i][j];
                            }
                        }

                        string strQueueWinner = dictQueueBreakout.Aggregate((l, r) => l.Value > r.Value ? l : r).Key;

                        Program.WriteStream(sw, string.Format("Actual: {0}\t\tQueue Recognized: {1}", gesture.First().Label, strQueueWinner));
                        if (strQueueWinner == gesture.First().Label)
                        {
                            nQueueCorrect++;
                        }
                        else
                        {
                            nQueueIncorrect++;
                        }

                        #endregion
                    }

                    Program.WriteStream(sw, string.Format("Sphere Correct: {0}\t\tSphere Incorrect: {1}\t\tSphere Percentage: {2:P}", nSphereCorrect, nSphereIncorrect, (double)nSphereCorrect / (nSphereCorrect + nSphereIncorrect)));
                    Program.WriteStream(sw, string.Format("Queue Correct: {0}\t\tQueue Incorrect: {1}\t\tQueue Percentage: {2:P}", nQueueCorrect, nQueueIncorrect, (double)nQueueCorrect / (nQueueCorrect + nQueueIncorrect)));

                    Program.WriteStream(sw, System.Environment.NewLine);
                    Program.WriteStream(sw, System.Environment.NewLine);

                    #endregion

                    System.Console.Beep();
                    System.Console.Beep();

                    #region GC Cleanup

                    sphere.Cleanup();
                    GC.Collect(GC.MaxGeneration);
                    GC.WaitForPendingFinalizers();

                    // This is where you check the CLR profiler

                    #endregion

                    char key;
                    do
                    {
                        System.Console.WriteLine("Hit 'y' to continue...");
                        key = System.Console.ReadKey().KeyChar;
                    } while (key.ToString().ToUpper() != "Y");

                    do
                    {
                        System.Console.WriteLine("Hit 'y' AGAIN to continue...");
                        key = System.Console.ReadKey().KeyChar;
                    } while (key.ToString().ToUpper() != "Y");

                    #region Serialize Sphere

                    if (false)
                    {
                        using (System.IO.FileStream fs = new System.IO.FileStream(string.Format(@".\{0}-{1}-{2}-{3}.serialized", bIsSTRHC1 ? "STRHC1" : "STRHC2", nQueuePartitions, nSlotsPerQueuePartition, kvp.Key), System.IO.FileMode.Create))
                        {
                            BinaryFormatter bf = new BinaryFormatter();
                            bf.Serialize(fs, sphere);
                        }
                    }

                    #endregion
                }
            }
        }