예제 #1
0
        // метод должен возвратить целый лог действий
        public static List <StepCompositionLog> Compose(out string error_msg)
        {
            error_msg = "";

            //с этого обязательно должен начинаться метод
            var log    = new List <StepCompositionLog>();
            var boards = new List <List <int> >();

            // таким макаром добавляется новая плата в список плат
            boards.Add(new List <int>());
            // таким образом добавляем в 1-ую плату 3-ий элемент
            boards[0].Add(3);



            // в конце каждого шага должно присутствовать это
            string msg  = "тут результаты выполнения шага";
            var    step = new StepCompositionLog(boards, msg);



            // этим метод должен обязательно закончиться
            return(log);
        }
예제 #2
0
        /// <summary>
        /// Последовательная компоновка по гиперграфу
        /// </summary>
        /// <param name="countOfBoards">Ограничение на количество узлов</param>
        /// <param name="limitsOfWires">Ограничение на количество связей</param>
        /// <returns>Полный лог действий</returns>
        public static List <StepCompositionLog> Compose(int countOfElements, int limitsOfWires, out string error_msg)
        {
            var log = new List <StepCompositionLog>();

            var sch = ApplicationData.ReadScheme(out error_msg);

            if (error_msg != "")
            {
                return(log);
            }

            // считываем матрицу Q
            Matrix <int> Q = sch.MatrixQ;

            var E  = new List <int>(); // множество распределённых элементов
            var nE = new List <int>(); // множество нераспределённых элементов
            var L1 = new List <int>();
            var L2 = new List <int>();
            var L3 = new List <int>();

            // формируем множество распределённых элементов
            E.Add(0); // только разъём
            // формируем множество нераспределённых элементов
            for (int i = 1; i < Q.RowsCount; i++)
            {
                nE.Add(i); // все элементы кроме разъёма
            }
            // создаём список элементов в узлах
            var boards = new List <List <int> >();
            int elem;

            while (nE.Count != 0)             // пока не распределили все элементы
            {
                boards.Add(new List <int>()); // добавляем новую плату
                L1.Clear();

                foreach (int it in nE)
                {
                    L1.Add(DefineL1(it, E, Q));  // вычисляем для каждого элемента L1
                }
                elem = nE[L1.IndexOf(L1.Max())]; // на плату отправляется элемент с максимальным L1

                // начинаем логирование действия
                // формируем строку - обоснование
                string msg = "";
                for (int i = 0; i < nE.Count; i++)
                {
                    msg += "Для D" + nE[i] + " - L1 = " + L1[i] + "\n";
                }
                msg += "Поместили элемент D" + elem + " на " + boards.Count + " плату - он имеет максимальный L1";

                boards.Last().Add(elem);      // помещаем элемент на плату
                E.Add(elem); nE.Remove(elem); // корректируем списки

                var step = new StepCompositionLog(boards, msg);
                log.Add(step);

                while (boards.Last().Count < countOfElements)
                {
                    if (nE.Count == 0)
                    {
                        break;
                    }
                    L2.Clear(); L3.Clear();

                    int previousElem = elem;
                    foreach (int it in nE)
                    {
                        var Z = boards.Last().GetRange(0, boards.Last().Count);

                        L2.Add(DefineL2(previousElem, it, Z, Q)); // вычисляем для каждого элемента L2
                        if (L2.Last() <= limitsOfWires)
                        {
                            L3.Add(DefineL3(previousElem, it, Q)); // и L3, если соблюдено условие о проводах
                        }
                        else
                        {
                            L3.Add(-1);
                        }
                    }

                    bool fault = true; // флаг того, что ни один элемент нельзя разместить
                    foreach (int it in L3)
                    {
                        if (it != -1)
                        {
                            fault = false;
                            break;
                        }
                    }

                    if (fault)
                    {
                        msg = "";
                        for (int i = 0; i < nE.Count; i++)
                        {
                            msg += "Для D" + nE[i] + " - L2 = " + L2[i] + ", L3 = " + L3[i] + "\n";
                        }

                        msg += "Ни один из элементов нельзя поместить на плату, потому что не соблюдается условие на ограничение связей";
                        step = new StepCompositionLog(boards, msg);
                        log.Add(step);
                        break;
                    }
                    else
                    {
                        elem = nE[L3.IndexOf(L3.Max())];

                        // начинаем логирование действия
                        // формируем строку - обоснование
                        msg = "";
                        for (int i = 0; i < nE.Count; i++)
                        {
                            msg += "Для D" + nE[i] + " - L2 = " + L2[i] + ", L3 = " + L3[i] + "\n";
                        }
                        msg += "Поместили элемент D" + elem + " на " + boards.Count + " плату - он имеет максимальный L3";

                        boards.Last().Add(elem);      // помещаем элемент на плату
                        E.Add(elem); nE.Remove(elem); // корректируем списки

                        step = new StepCompositionLog(boards, msg);
                        log.Add(step);
                    }
                }
            }

            // в качестве результата выполнения метода возвращаем целый пошаговый лог
            return(log);
        }
예제 #3
0
        /// <summary>
        /// Последовательная компоновка по мультиграфу
        /// </summary>
        /// <param name="countOfBoards">Ограничение на количество узлов</param>
        /// <param name="limitsOfWires">Ограничение на количество связей</param>
        /// <returns>Полный лог действий</returns>
        public static List <StepCompositionLog> Compose(int countOfElements, int limitsOfWires, out string error_msg)
        {
            var log = new List <StepCompositionLog>();

            var sch = ApplicationData.ReadScheme(out error_msg);

            if (error_msg != "")
            {
                return(log);
            }

            // считываем матрицу R
            Matrix <int> R = sch.MatrixR;

            var EE      = new List <int>(); // множество всех элементов кроме раъёма (для логирования)
            var E       = new List <int>(); // множество распределённых элементов
            var nE      = new List <int>(); // множество нераспределённых элементов
            var Ro      = new List <int>(); // локальные степени вершин
            var RoConst = new List <int>(); // неизменные локальные степени вершин

            for (int i = 0; i < R.ColsCount - 1; i++)
            {
                Ro.Add(0); RoConst.Add(0);
            }
            // заполняем массив Ro суммой по столбцам (не учитывая разъём)
            for (int i = 0; i < R.ColsCount - 1; i++)
            {
                for (int j = 0; j < R.ColsCount - 1; j++)
                {
                    Ro[i]      += R[i + 1, j + 1];
                    RoConst[i] += R[i + 1, j + 1];
                }
            }

            // формируем множество распределённых элементов
            E.Add(0); // только разъём
            // формируем множество нераспределённых элементов
            for (int i = 1; i < R.RowsCount; i++)
            {
                nE.Add(i); // все элементы кроме разъёма
                EE.Add(i);
            }

            // создаём список элементов в узлах
            var boards = new List <List <int> >();
            int elem;
            int wires;                             // количество внешних связей

            while (nE.Count != 0)                  // пока не распределили все элементы
            {
                boards.Add(new List <int>());      // добавляем новую плату

                List <int> min = new List <int>(); // массив элементов с минимальным значением локальной степени
                foreach (int e in nE)
                {
                    if (Ro[e - 1] == Ro.Min())
                    {
                        min.Add(e);
                    }
                }
                if (min.Count == 1)
                {
                    elem = min[0]; // если такой элемент один, то он отправляется на плату
                }
                else
                {
                    // если таких элементов несколько, нужно выбрать такой, который имеет наименьшее количество инцедентных вершин
                    List <int> incidents = new List <int>();
                    foreach (int m in min)
                    {
                        incidents.Add(GetIncidents(m, R).Count);
                    }
                    elem = min[incidents.IndexOf(incidents.Min())];
                }


                // начинаем логирование действия
                // формируем строку - обоснование
                string msg = "";
                for (int i = 0; i < Ro.Count; i++)
                {
                    if (Ro[i] != int.MaxValue)
                    {
                        msg += "Для D" + EE[i] + " - локальная степень вершины = " + Ro[i] + "\n";
                    }
                }
                msg += "Поместили элемент D" + elem + " на " + boards.Count +
                       " плату - он имеет минимальную локальную степень и минимальное число инцидентных вершин";

                boards.Last().Add(elem);      // помещаем элемент на плату
                E.Add(elem); nE.Remove(elem); // корректируем списки
                wires        = Ro[elem - 1];
                Ro[elem - 1] = int.MaxValue;

                var step = new StepCompositionLog(boards, msg);
                log.Add(step);


                while (boards.Last().Count < countOfElements)
                {
                    if (nE.Count == 0)
                    {
                        break;
                    }

                    List <int> incidents = new List <int>();
                    foreach (int number in boards.Last())
                    {
                        List <int> l = GetIncidents(number, R); // инцидентные вершины
                        foreach (int buf in E)
                        {
                            l.Remove(buf); // удаляем вершины из множества распределённых элементов
                        }
                        incidents.AddRange(l);
                    }
                    incidents = incidents.Distinct().ToList();

                    if (incidents.Count == 0)
                    {
                        msg  = "Нет инцидентных вершин";
                        step = new StepCompositionLog(boards, msg);
                        log.Add(step);
                        break;
                    }

                    List <int> Delta = new List <int>(); // приращения
                    foreach (int it in incidents)
                    {
                        var X = boards.Last().GetRange(0, boards.Last().Count);

                        int delta = RoConst[it - 1] - 2 * GetCountOfWires(it, R, X);
                        Delta.Add(delta);
                    }

                    if (Delta.Min() + wires <= limitsOfWires) // выбираем элемент с минимальным приращением
                    {
                        elem = incidents[Delta.IndexOf(Delta.Min())];
                        msg  = "Количество внешних связей = " + wires + "\n";
                        for (int i = 0; i < incidents.Count; i++)
                        {
                            msg += "Для D" + incidents[i] + " приращение равно " + Delta[i] + "\n";
                        }

                        msg += "Поместили элемент D" + elem + " на " + boards.Count + " плату - он имеет минимальное приращение";

                        boards.Last().Add(elem);      // помещаем элемент на плату
                        E.Add(elem); nE.Remove(elem); // корректируем списки
                        wires       += Delta.Min();
                        Ro[elem - 1] = int.MaxValue;

                        step = new StepCompositionLog(boards, msg);
                        log.Add(step);
                    }
                    else
                    {
                        msg = "Количество внешних связей = " + wires + "\n";
                        for (int i = 0; i < incidents.Count; i++)
                        {
                            msg += "Для D" + incidents[i] + " приращение равно " + Delta[i] + "\n";
                        }

                        msg += "Ни один из элементов нельзя поместить на плату, потому что не соблюдается условие на ограничение связей";
                        step = new StepCompositionLog(boards, msg);
                        log.Add(step);
                        break;
                    }
                }
            }

            // в качестве результата выполнения метода возвращаем целый пошаговый лог
            return(log);
        }