// метод должен возвратить целый лог действий 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); }
/// <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); }
/// <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); }