Exemple #1
0
        private static unsafe double[][] SolveKMeans(PocketData[] pockets)
        {
            Kml.Init(null);

            Kml.Parameters kmParams = new Kml.Parameters();

            kmParams.SetDefaultTerm();
            kmParams.dim       = _cmdLine.Dim;
            kmParams.term_st_a = _cmdLine.Stages;
            kmParams.term_st_b = kmParams.term_st_c = kmParams.term_st_d = 0;
            kmParams.seed      = 1;
            kmParams.k         = _cmdLine.K;
            kmParams.n         = _cmdLine.UsePocketCounts ? 1326: 169;
            kmParams.Allocate();

            Console.WriteLine("Data passed to kml:");
            int p = 0;

            for (int pocket = 0; pocket < pockets.Length; ++pocket)
            {
                int count = _cmdLine.UsePocketCounts ? HePocket.KindToRange((HePocketKind)pocket).Length : 1;
                for (int i = 0; i < count; ++i)
                {
                    for (int d = 0; d < _cmdLine.Dim; ++d)
                    {
                        double value             = pockets[pocket].Value[d];
                        *kmParams.GetPoint(p, d) = value;
                        Console.Write(value.ToString(CultureInfo.InvariantCulture) + " ");
                    }
                    Console.WriteLine();
                    ++p;
                }
            }
            Console.WriteLine();
            Debug.Assert(!_cmdLine.UsePocketCounts || p == 1326);

            Kml.KML_Hybrid(&kmParams);

            double[][] centers = new double[_cmdLine.K][].Fill(i => new double[_cmdLine.Dim]);

            for (int c = 0; c < kmParams.k; ++c)
            {
                for (int d = 0; d < kmParams.dim; ++d)
                {
                    centers[c][d] = *kmParams.GetCenter(c, d);
                }
            }

            kmParams.Free();

            return(centers);
        }
Exemple #2
0
        public void Test_Hybrid()
        {
            Kml.Init(Path.GetDirectoryName(CodeBase.Get(Assembly.GetExecutingAssembly())));

            Kml.Parameters p = new Kml.Parameters();

            try
            {
                p.n   = 20;
                p.k   = 4;
                p.dim = 2;

                p.term_st_a           = 50;
                p.term_st_b           = p.term_st_c = p.term_st_d = 0;
                p.term_minConsecRDL   = 0.2;
                p.term_minAccumRDL    = 0.1;
                p.term_maxRunStage    = 100;
                p.term_initProbAccept = 0.50;
                p.term_tempRunLength  = 10;
                p.term_tempReducFact  = 0.75;
                p.seed = 4;

                p.Allocate();

                for (int i = 0; i < p.n; ++i)
                {
                    for (int d = 0; d < p.dim; ++d)
                    {
                        *p.GetPoint(i, d) = _data1[i * p.dim + d];
                    }
                }
                Kml.KML_Hybrid(&p);

                p.PrintCenters(Console.Out);

                VerifyResult(p, _data1, _data1_expCenters, _data1_expCenterAssignments);
            }
            finally
            {
                p.Free();
            }
        }
        /// <summary>
        /// Run k-means.
        /// Returns hand values.
        /// </summary>
        protected double[][] CalcValuesAndKMeans(KMeansNode parentKmNode, int round, McHand[] hands, out double[][] centers)
        {
            double [][] values = new double[hands.Length][].Fill(i => new double[Dim]);

            double[] min = new double[Dim].Fill(double.MaxValue);
            double[] max = new double[Dim].Fill(double.MinValue);

            for (int i = 0; i < hands.Length; ++i)
            {
                CalculateValue(hands[i].Cards, hands[i].Length, values[i]);
                VectorS.UpdateMin(values[i], min);
                VectorS.UpdateMax(values[i], max);
            }
            double [] delta = VectorS.Sub(max, min);

            if (_normalizeHandValues)
            {
                for (int i = 0; i < values.Length; ++i)
                {
                    VectorS.NormalizeByDiff(values[i], min, delta);
                }
                min.CopyTo(parentKmNode.ValueMin, 0);
                delta.CopyTo(parentKmNode.ValueBounds, 0);
            }

            if (_printHandValues || _printHands)
            {
                for (int i = 0; i < values.Length; ++i)
                {
                    if (_printHands)
                    {
                        Console.Write("{0} ", StdDeck.Descriptor.GetCardNames(hands[i].Cards, 0, hands[i].Length));
                    }
                    if (_printHandValues)
                    {
                        PrintVector(values[i]);
                    }
                    Console.WriteLine();
                }
            }

            // Calcualate number of clusters.
            int k           = MaxBucketCounts[round];
            int adaptingDim = -1;

            for (int d = 0; d < Dim; ++d)
            {
                double clusterSize = ClusterSizes[d][round];
                if (clusterSize != 0)
                {
                    int clCount = (int)Math.Round(delta[d] / clusterSize, 0);
                    if (clCount < k)
                    {
                        adaptingDim = d;
                        k           = clCount;
                    }
                }
            }
            // Make sure number of clusters is in the given range.
            k = Math.Max(MinBucketCounts[round], k);

            if (IsVerbose)
            {
                Console.Write("Min: ");
                PrintVector(min);
                Console.Write(" Max: ");
                PrintVector(max);
                Console.Write(" Delta: ");
                PrintVector(delta);
                if (k < MaxBucketCounts[round])
                {
                    Console.Write(" K adapted to {0} by dim: {1}", k, adaptingDim);
                }
                Console.WriteLine();
            }

            double [][] differentValues      = new double[k][].Fill(i => new double[Dim]);
            int         differentValuesCount = 0;

            for (int i = 0; i < values.Length; ++i)
            {
                for (int j = 0; j < differentValuesCount; ++j)
                {
                    if (VectorS.AreEqual(values[i], differentValues[j]))
                    {
                        goto RepeatedValue;
                    }
                }
                values[i].CopyTo(differentValues[differentValuesCount], 0);
                differentValuesCount++;
                if (differentValuesCount == k)
                {
                    break;
                }
                RepeatedValue :;
            }
            if (differentValuesCount < k)
            {
                // Too few different values to build k clusters. Do not run k-means, it may hang.
                centers = differentValues;
                Array.Resize(ref centers, differentValuesCount);
                if (IsVerbose)
                {
                    Console.WriteLine("Only {0} different values found. Set cluster count, do not run kmeans", differentValuesCount);
                }
                return(values);
            }

            _kmParameters.k = k;
            _kmParameters.n = values.Length;

            _kmParameters.Allocate();

            for (int i = 0; i < values.Length; ++i)
            {
                for (int d = 0; d < Dim; ++d)
                {
                    *_kmParameters.GetPoint(i, d) = values[i][d];
                }
            }

            fixed(Kml.Parameters *kmlp = &_kmParameters)
            {
                Kml.KML_Hybrid(kmlp);
            }

            centers = new double[_kmParameters.k][].Fill(i => new double[Dim]);
            for (int c = 0; c < _kmParameters.k; ++c)
            {
                for (int d = 0; d < Dim; ++d)
                {
                    centers[c][d] = *_kmParameters.GetCenter(c, d);
                }
            }
            _kmParameters.Free();

            return(values);
        }