public static CategClusterSet ProcessAsync(OrdModelView model, int nClusters, CancellationToken cancellationToken) { if ((model == null) || (nClusters < 2)) { return null; } if (cancellationToken.IsCancellationRequested) { return null; } var rd = new Random(); CategClusterSet oRet = new CategClusterSet(model); Cluster[] cc = new Cluster[nClusters]; IndivData[] inds = oRet.Indivs.ToArray(); int nMax = inds.Length; if (nMax < nClusters) { return null; } HashSet<int> oCur = new HashSet<int>(); for (int i = 0; i < nClusters; ++i) { int nx = rd.Next(0, nMax); while (nx >= nMax) { nx = rd.Next(nMax); } IndivData indiv = inds[nx]; int index = indiv.IndivIndex; while (oCur.Contains(index)) { nx = rd.Next(0, nMax); while (nx >= nMax) { nx = rd.Next(0, nMax); } indiv = inds[nx]; index = indiv.IndivIndex; } oCur.Add(index); var xc = new Cluster(indiv, ClassificationType.Utility); xc.Name = String.Format("CU{0}", i + 1); xc.Index = i; cc[i] = xc; }// i oRet.Clusters = cc.ToList(); double xx = oRet.compute_global_crit(cancellationToken); oRet.GlobalCrit = xx; if (cancellationToken.IsCancellationRequested) { return null; } foreach (var ind in inds) { if (cancellationToken.IsCancellationRequested) { return null; } if (!oCur.Contains(ind.IndivIndex)) { if (!oRet.processOne(ind, cancellationToken)) { return null; } } }// inds return oRet; }