コード例 #1
0
ファイル: CureAlgorithm.cs プロジェクト: shurik88/Algorithms
        /// <summary>
        /// Инициализация начальных кластеров
        /// </summary>
        /// <param name="points">Исходные точки</param>
        /// <returns>Кластера с дополнительной информацией <seealso cref="CalculatedCluster"/></returns>
        private Dictionary <Guid, CalculatedCluster> InitClusters(IEnumerable <CurePoint> points)
        {
            var clusters = points.Select(x => new CureCluster(x)).ToList();
            var dict     = new Dictionary <Guid, CalculatedCluster>();

            foreach (var cluster1 in clusters)
            {
                var         minDistance = Double.MaxValue;
                CureCluster closest     = null;
                foreach (var cluster2 in clusters)
                {
                    if (cluster1 == cluster2)
                    {
                        continue;
                    }
                    var distance = Distance(cluster1, cluster2);
                    if (distance < minDistance)
                    {
                        minDistance = distance;
                        closest     = cluster2;
                    }
                }
                dict.Add(cluster1.Number, new CalculatedCluster {
                    Closest = closest, Cluster = cluster1, Distance = minDistance
                });
            }

            return(dict);
        }
コード例 #2
0
ファイル: CureAlgorithm.cs プロジェクト: shurik88/Algorithms
        /// <summary>
        /// Слияние кластеров
        /// </summary>
        /// <param name="cluster1">Кластер№1</param>
        /// <param name="cluster2">Кластер№2</param>
        /// <returns>Итоговый кластер</returns>
        private CureCluster MergeClusters(CureCluster cluster1, CureCluster cluster2)
        {
            var totalPoints = cluster1.Points.Union(cluster2.Points).ToList();

            var meanPoint = new double[totalPoints.First().Vector.Length];

            for (var i = 0; i < meanPoint.Length; ++i)
            {
                meanPoint[i] = totalPoints.Sum(x => x.Vector[i]) / totalPoints.Count * 1.0;
            }

            var ordered = totalPoints
                          .Select(x => new
            {
                Point    = x,
                Distance = _distanceCalculator.GetDistance(meanPoint, x.Vector)
            })
                          .OrderBy(x => x.Distance).ToList();

            var rep = (_c > ordered.Count ? ordered : ordered.Take(_c))
                      .Select(x => x.Point.Vector.Select((v, i) => v + _a * (meanPoint[i] - v)).ToArray())
                      .ToList();

            return(new CureCluster(totalPoints, rep));
        }
コード例 #3
0
ファイル: CureAlgorithm.cs プロジェクト: shurik88/Algorithms
        /// <summary>
        /// Перерасчет метрки кластеров для определенного кластера с номером
        /// </summary>
        /// <param name="clusters">Кластеры</param>
        /// <param name="number">Номер кластера</param>
        private void RecalculateClosest(Dictionary <Guid, CalculatedCluster> clusters, Guid number)
        {
            var         minDistance = Double.MaxValue;
            CureCluster closest     = null;

            foreach (var pair in clusters)
            {
                if (pair.Key == number)
                {
                    continue;
                }
                var distance = Distance(pair.Value.Cluster, clusters[number].Cluster);
                if (distance < minDistance)
                {
                    minDistance = distance;
                    closest     = pair.Value.Cluster;
                }
            }
            clusters[number].Closest  = closest;
            clusters[number].Distance = minDistance;
        }
コード例 #4
0
ファイル: CureAlgorithm.cs プロジェクト: shurik88/Algorithms
        /// <summary>
        /// Расчет растояния между двумя кластерами
        /// </summary>
        /// <param name="cluster1">Калстер№1</param>
        /// <param name="cluster2">Кластер№2</param>
        /// <returns>Расстояние</returns>
        public double Distance(CureCluster cluster1, CureCluster cluster2)
        {
            var repPoints = cluster2.RepPoints.ToList();

            var min = _distanceCalculator.GetDistance(cluster1.RepPoints.First(), repPoints.First());

            foreach (var repPoint1 in cluster1.RepPoints)
            {
                foreach (var repPoint2 in repPoints)
                {
                    var distance = _distanceCalculator.GetDistance(repPoint1, repPoint2);
                    if (distance < min)
                    {
                        min = distance;
                    }
                }
            }
            var maxWeights = Math.Max(cluster1.Points.Sum(x => x.Weight), cluster2.Points.Sum(x => x.Weight));

            return(maxWeights > _averageCount ? (min * maxWeights * _targetClustersCount / _averageCount) : min);
        }