コード例 #1
0
        /// <summary>
        /// начальная инциализация
        /// </summary>
        /// <param name="treader"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        public static ClastersSet <T> Initialiazation(IClopeReader <Transaction <T> > treader, double r)
        {
            var res = new ClastersSet <T>();

            //
            // 1. начальная инициализация набора кластеров
            //
            // по порядку перебираются все транзакции, и для каждой из них происходит вычисление цены ее добавления в существующие кластеры или же в новый, изначально пустой, кластер.
            // Исходя из вычисленных значений, каждой транзакции назначается кластер(какой - либо из уже существующих или новый)
            // выбирается кластер(при необходимости создается новый), для которого было получено максимальное значение цены добавления данной транзакции.
            // Таким образом происходит начальное распределение транзакций по кластерам(инициализация кластеризации).
            int             iteration    = 0;
            var             max_deltaadd = new SearchValues <T>(null, 0);
            double          res_add;
            Transaction <T> transaction; // не будем каждый раз выделять под нее память.
            Claster <T>     claster_new; // создадимо его только если он будет нужен
            Claster <T>     claster_cur; // в цикле не будет инициализироваться новая память

            treader.BeginRead();

            while (!treader.EndOF)
            {
                iteration++;
                transaction = treader.ReadNext();

                // начальные значения для поиска (возможно быстрее прям здесь по порядку обнулить поля, чем вызывать функцию)
                max_deltaadd.Reset();

                res_add = 0;

                for (int i = 0; i < res.Count; i++)
                {
                    claster_cur = res[i];
                    res_add     = DeltaAdd(claster_cur, transaction, r); // 48% занимает от времени инициализации

                    if (max_deltaadd.Value < res_add)
                    {
                        max_deltaadd.Claster = claster_cur;
                        max_deltaadd.Value   = res_add;
                        max_deltaadd.Index   = i;
                    }
                }

                res_add = DeltaAdd(null, transaction, r);
                if (max_deltaadd.Value < res_add)
                {
                    claster_new = new Claster <T>();

                    max_deltaadd.Claster = claster_new;
                    max_deltaadd.Value   = res_add;
                    max_deltaadd.Index   = res.Count;

                    // если выбран новый кластер, то добавляем его в массив кластеров
                    res.Add(claster_new);
                }

                // добавляем транзакцию в максимально увеличивающий дельту кластер
                max_deltaadd.Claster.AddTransaction(transaction);
                treader.Write(transaction, max_deltaadd.Index);
            }

            treader.EndRead();

            return(res);
        }
コード例 #2
0
        /// <summary>
        /// 2. Уточняющие итерации
        /// </summary>
        /// <param name="treader"></param>
        /// <param name="r"></param>
        /// <param name="res"></param>
        internal static void Clasterization(IClopeReader <Transaction <T> > treader, double r, ClastersSet <T> res)
        {
            // число перемещений
            int         replace_count;
            double      res_add;
            var         max_deltaadd = new SearchValues <T>(null, 0); // ициниализация из образца
            Claster <T> claster_for;
            Claster <T> claser_new;

            // начало цикла repeat
            do
            {
                replace_count = 0;
                treader.BeginRead();

                while (!treader.EndOF)
                {
                    var transaction = treader.ReadNext();

                    var current_claster = res[transaction.ClusterNumber];

                    var deltaremove = DeltaRemove(current_claster, transaction, r);

                    max_deltaadd.Reset();

                    for (int i = 0; i < res.Count; i++)
                    {
                        claster_for = res[i];
                        if (claster_for == current_claster)
                        {
                            continue;
                        }

                        res_add = DeltaAdd(claster_for, transaction, r); // 62% занимает при кластеризации

                        //если для транзакции найден кластер с большей ценой перемещения, сохраняем эту информацию
                        if (res_add + deltaremove > max_deltaadd.Value)
                        {
                            max_deltaadd.Claster = claster_for;
                            max_deltaadd.Value   = res_add;
                            max_deltaadd.Index   = i;
                        }
                    }

                    res_add = DeltaAdd(null, transaction, r);
                    if (res_add + deltaremove > max_deltaadd.Value)
                    {
                        claser_new = new Claster <T>();

                        max_deltaadd.Claster = claser_new;
                        max_deltaadd.Value   = res_add;
                        max_deltaadd.Index   = res.Count;

                        // если выбран новый кластер, то добавляем его в массив кластеров
                        res.Add(claser_new);
                    }

                    // было найдено выгодное перемещение
                    if (max_deltaadd.Claster != null && current_claster != max_deltaadd.Claster)
                    {
                        current_claster.RemoveTransaction(transaction);
                        max_deltaadd.Claster.AddTransaction(transaction);

                        treader.Write(transaction, max_deltaadd.Index);
                        replace_count++;
                    }
                }

                treader.EndRead();

                // удаляем пустые кластеры
                foreach (var item in res.Where(x => x.Size == 0 || x.W == 0).ToArray())
                {
                    res.Remove(item);
                }
            }while (replace_count != 0);
        }