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); }
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); }