public static DecisionTree CreateTree(int[] indexes, double[,] xy, int nclasses, double pcoeff, double vcoeff) { if (xy == null) { throw new ArgumentException("xy is null", nameof(xy)); } int npoints = xy.GetLength(0); int nvars = xy.GetLength(1) - 1; int modNpoints = (int)(npoints * pcoeff); // столько значений надо нагенерировать int modNvars = (int)(nvars * vcoeff); // столько переменных используем if (modNvars < 1) { throw new ArgumentException("vcoeff too small", nameof(vcoeff)); } int[] vidxes = Enumerable.Range(0, nvars).ToArray(); if (modNvars < nvars) { vidxes = Enumerable.Range(0, nvars).OrderBy(c => RandomGen.GetDouble()).Take(modNvars).ToArray(); } double[,] nxy = new double[modNpoints, modNvars + 1]; // сами значения int nk = 0; // столько нагенерировали var exists = new Dictionary <int, int>(); if (indexes == null) { // basic tree while (nk < modNpoints) { for (int i = 0; i < modNpoints; i++) { int sn = (int)(RandomGen.GetDouble() * npoints); // selection distribution if (sn >= npoints) { continue; } if (exists.ContainsKey(sn)) { continue; // такой ключ уже был } exists.Add(sn, 0); for (int j = 0; j < modNvars; j++) { nxy[i, j] = xy[sn, vidxes[j]]; } nxy[i, modNvars] = xy[sn, nvars]; nk++; if (nk >= modNpoints) { break; } } if (nk >= modNpoints) { break; } } } else { // tree, with distribution selection while (nk < modNpoints) { for (int i = 0; i < modNpoints; i++) { int sn = (int)(RandomGen.GetTrangle() * npoints); // selection distribution if (sn >= indexes.Length) { continue; } if (exists.ContainsKey(sn)) { continue; // такой ключ уже был } exists.Add(sn, 0); int sidx = indexes[sn]; for (int j = 0; j < modNvars; j++) { nxy[i, j] = xy[sidx, vidxes[j]]; } nxy[i, modNvars] = xy[sidx, nvars]; nk++; if (nk >= modNpoints) { break; } } if (nk >= modNpoints) { break; } } } var ridxes = exists.Keys.ToArray(); return(CreateTree(nxy, nclasses, nvars, modNpoints, modNvars, vidxes, ridxes)); }