/// <summary> /// конструктор алгоритма /// </summary> /// <param name="xDist">distance function for input data space</param> /// <param name="yDist">distance function for preprocessed data space</param> /// <param name="xyConv">space conversion function (in some cases could be similar to feature mapping)</param> /// <param name="comparePointFunction">nearest neihbor function for clusters, shoud return constant -1 to be trivial</param> /// <param name="clusterFusionCriteria">similarity function to define cluster fusion, should return constant -1 to be trivial</param> /// <param name="clusterDivider">a function for spliting cluster in two, should return empty collection of clusters to be trivial</param> /// <param name="clusterSortCriteria">a function for cluster comparing</param> /// <param name="cnt">cluster center function</param> public ClusterAlgorithm(distanceFunction xDist, distanceFunction yDist, spaceConversionFunction xyConv, sameCluster comparePointFunction, similarClusters clusterFusionCriteria, splitCluster clusterDivider, comapreClusters clusterSortCriteria, clusterCenterFunction cnt, bool isSplitTrivial = false) { this.xDist = xDist; this.yDist = yDist; this.xyConv = xyConv; this.comparePointFunction = comparePointFunction; this.clusterFusionCriteria = clusterFusionCriteria; this.clusterDivider = clusterDivider; this.clusterSortCriteria = clusterSortCriteria; this.cntFunc = cnt; this.isSplitingTrivial = isSplitTrivial; }
public static float ComapreClustersBySize(Cluster k1, Cluster k2, distanceFunction yDist, clusterCenterFunction cnf, double[] cnfPars) { return(k1.Size - k2.Size); }
public static ICollection <Cluster> SplitClusterGraph(Cluster k1, distanceFunction yDist, clusterCenterFunction cnf, double[] cnfPars, double[] splitPars) { List <Edge> edges = new List <Edge>(GetEdgesForCluster(k1, yDist)); List <int> inds = new List <int>(); for (int i = 0; i < k1.Size; i++) { inds.Add(i); } for (int i = 0; i < edges.Count; i++) { if (edges[i].Distance > splitPars[0]) { edges.RemoveAt(i); i--; } } List <ICollection <int> > components = new List <ICollection <int> >(GetLinkedComponents(edges, inds)); List <Cluster> res = new List <Cluster>(); for (int i = 0; i < components.Count; i++) { List <double[]> data = new List <double[]>(); List <int> gInds = new List <int>(); for (int j = 0; j < components[i].Count; j++) { data.Add(k1.GetElementByLocalIndex(components[i].ElementAt(j))); gInds.Add(k1.GetGlobalIndexByLocal(components[i].ElementAt(j))); } res.Add(new Cluster(gInds.ToArray(), data)); } return(res); }
public static ICollection <Cluster> SplitClusterTrivial(Cluster k1, distanceFunction yDist, clusterCenterFunction cnf, double[] cnfPars, double[] splitPars) { return(new Cluster[] { k1 }); }
public static float SimilarClusterBrute(Cluster y1, Cluster y2, distanceFunction yDist, clusterCenterFunction cnf, double[] cnfPars) { double[] center1 = cnf(y1, yDist, cnfPars), center2 = cnf(y2, yDist, cnfPars); double max1 = yDist(center1, y1.GetElementByLocalIndex(0)), max2 = yDist(center2, y2.GetElementByLocalIndex(0)); double tmpDist; for (int i = 0; i < y1.Size; i++) { tmpDist = yDist(y1.GetElementByLocalIndex(i), center1); if (tmpDist > max1) { max1 = tmpDist; } } for (int i = 0; i < y2.Size; i++) { tmpDist = yDist(y2.GetElementByLocalIndex(i), center2); if (tmpDist > max2) { max2 = tmpDist; } } double cDist = yDist(center1, center2); double maxAvg = (max1 + max2) / 2; if (cDist < maxAvg) { return(1.0f); } else { return((float)maxAvg / (float)cDist); } }
public static float SameClusterBrute(Cluster y1, Cluster y2, distanceFunction yDist, clusterCenterFunction cnf, double[] cnfPars) { double[] center1 = cnf(y1, yDist, cnfPars), center2 = cnf(y2, yDist, cnfPars); double max1 = yDist(center1, y1.GetElementByLocalIndex(0)), max2 = yDist(center2, y2.GetElementByLocalIndex(0)); double tmpDist; for (int i = 0; i < y1.Size; i++) { tmpDist = yDist(y1.GetElementByLocalIndex(i), center1); if (tmpDist > max1) { max1 = tmpDist; } } for (int i = 0; i < y2.Size; i++) { tmpDist = yDist(y2.GetElementByLocalIndex(i), center2); if (tmpDist > max2) { max2 = tmpDist; } } int counter1 = 0, counter2 = 0; for (int i = 0; i < y1.Size; i++) { tmpDist = yDist(y1.GetElementByLocalIndex(i), center2); if (tmpDist < max1) { counter1++; } } for (int i = 0; i < y2.Size; i++) { tmpDist = yDist(y2.GetElementByLocalIndex(i), center1); if (tmpDist < max2) { counter2++; } } //подсчёт float pre1 = ((float)counter1) / y1.Size, pre2 = ((float)counter2) / y2.Size; return(pre1 * pre2); }