public static void DynamicProgrammingPrintResult(List <Container> listContainers, int countFloor, ResultDataAfterGrouping resDataAftGrouping, Label resultGreedyLabel) { resultGreedyLabel.Text += string.Format(MessagesText.ValueFunctionalF, listContainers.Last().FineChain *countFloor + resDataAftGrouping.Fine) .ToString(CultureInfo.InvariantCulture); //Превращаем в список для удобного отображения var listOneFlat = new List <double>(); var listTwoFlat = new List <double>(); foreach (var container in listContainers) { //Приведение длин для конечного отображения var resultAddingPlace = ResultAddingPlace.CalculateAddingPlace(container.DataContainer, 0.3); listOneFlat.Add(resultAddingPlace.A1); listOneFlat.Add(resultAddingPlace.A2); listTwoFlat.Add(container.DataContainer.B1); listTwoFlat.Add(container.DataContainer.B2); } for (var numberFloor = 0; numberFloor < countFloor; ++numberFloor) { resultGreedyLabel.Text += MessagesText.DividingLine; PrintFloor(listOneFlat, resultGreedyLabel); resultGreedyLabel.Text += MessagesText.DividingLine; PrintFloor(listTwoFlat, resultGreedyLabel); PrintStroke(listOneFlat.Count, numberFloor, countFloor, resultGreedyLabel); } PrintExceedFlat(resDataAftGrouping.ListExcessOneFlat, resultGreedyLabel, MessagesText.RectanglesAiNotList); PrintExceedFlat(resDataAftGrouping.ListExcessTwoFlat, resultGreedyLabel, MessagesText.RectanglesBiNotList); }
public static ResultGreedyMethode GreedyMethode(DataMethode dataGrM, double firstOneFlat, string positionStart) { var listLenOneFlat = new List <double>(dataGrM.ListLenOneFlat); var listLenTwoFlat = new List <double>(dataGrM.ListLenTwoFlat); var resultGreedy = new ResultGreedyMethode(); var finalPlacementOneFlat = new double[dataGrM.OptCountFlatOnFloor]; var finalPlacementTwoFlat = new double[dataGrM.OptCountFlatOnFloor]; var maxFine = 0.0; var index1 = 0; // индексы нужны для удаления из второго списка var index2 = 0; for (var n = 0; n < dataGrM.OptCountFlatOnFloor; n = n + 2) // цикл заполнения секций { //Если есть ненулевое значение и оно встретилось в первый раз, то записываем его double choiceOneFlat; switch (positionStart) { case "First": choiceOneFlat = Math.Abs(firstOneFlat) > 1e-9 && resultGreedy.IsFlagFirstEntry ? firstOneFlat : listLenOneFlat[0]; break; case "Middle": choiceOneFlat = Math.Abs(firstOneFlat) > 1e-9 && resultGreedy.IsFlagFirstEntry ? firstOneFlat : listLenOneFlat[listLenOneFlat.Count / 2]; break; case "Penultimate": choiceOneFlat = Math.Abs(firstOneFlat) > 1e-9 && resultGreedy.IsFlagFirstEntry ? firstOneFlat : listLenOneFlat[listLenOneFlat.Count - 2]; break; default: throw new Exception(); } resultGreedy.IsFlagFirstEntry = false; var sortedListOneFlat = new List <double>(listLenOneFlat); sortedListOneFlat.Remove(choiceOneFlat); var fine = double.MaxValue; finalPlacementOneFlat[n] = choiceOneFlat; var arraySortedTwoFlat = listLenTwoFlat.ToArray(); for (var i = 0; i < listLenTwoFlat.Count; ++i) { for (var j = i + 1; j < listLenTwoFlat.Count; ++j) { foreach (var t in sortedListOneFlat) { double[] currentMassiv; Array.Copy(arraySortedTwoFlat, currentMassiv = new double[arraySortedTwoFlat.Length], arraySortedTwoFlat.Length); ApartureLen resultPackSectReverse; switch (dataGrM.OptCountFlatOnFloor - n) { case 2: { resultPackSectReverse = MethodsForApartureLen.CalculateOptimalPackContainer( new ApartureLen(choiceOneFlat, t, currentMassiv[j], currentMassiv[i]), dataGrM.WallsWidth); break; } default: resultPackSectReverse = new ApartureLen(double.MaxValue); break; } var resultPackSect = MethodsForApartureLen.CalculateOptimalPackContainer( new ApartureLen(choiceOneFlat, t, currentMassiv[i], currentMassiv[j]), dataGrM.WallsWidth); //Todo change expression 2.4 = parameters: p1 p2 /* * var currentFineReverse = * Math.Abs(Math.Round( * resultPackSectReverse.DataContainer.B1 + resultPackSectReverse.DataContainer.B2 + dataGrM.AddingB - * (resultPackSectReverse.DataContainer.A1 + resultPackSectReverse.DataContainer.A2 + dataGrM.AddingA) + resultPackSectReverse.ExtraSquare, 1)); + + var currentFine = + Math.Abs(Math.Round( + resultPackSect.DataContainer.B1 + resultPackSect.DataContainer.B2 + dataGrM.AddingB - + (resultPackSect.DataContainer.A1 + resultPackSect.DataContainer.A2 + dataGrM.AddingA) + resultPackSect.ExtraSquare, 1)); */ var currentFineReverse = Math.Abs(Math.Round( resultPackSectReverse.DataContainer.B1 - 2.4 + resultPackSectReverse.DataContainer.B2 - 2.4 + dataGrM.EntrywayPlusCorridor + 2 * dataGrM.WallsWidth - (resultPackSectReverse.DataContainer.A1 + 2.4 + resultPackSectReverse.DataContainer.A2 + 2.4 + 2 * dataGrM.WallsWidth) + resultPackSectReverse.ExtraSquare, 1)); var currentFine = Math.Abs(Math.Round( resultPackSect.DataContainer.B1 - 2.4 + resultPackSect.DataContainer.B2 - 2.4 + dataGrM.EntrywayPlusCorridor + 2 * dataGrM.WallsWidth - (resultPackSect.DataContainer.A1 + 2.4 + resultPackSect.DataContainer.A2 + 2.4 + 2 * dataGrM.WallsWidth) + resultPackSect.ExtraSquare, 1)); if (currentFineReverse < currentFine) { currentFine = currentFineReverse; resultPackSect = resultPackSectReverse; } if (!(currentFine < fine)) { continue; } fine = currentFine; finalPlacementTwoFlat[n] = resultPackSect.DataContainer.B1; index1 = i; finalPlacementTwoFlat[n + 1] = resultPackSect.DataContainer.B2; index2 = j; finalPlacementOneFlat[n + 1] = resultPackSect.DataContainer.A2; } } } //удаление занятых вариантов из списка и суммирование штрафа resultGreedy.Fine = Math.Round(resultGreedy.Fine + fine, 1); if (maxFine < fine) { maxFine = fine; resultGreedy.NewFirstOneFlat = finalPlacementOneFlat[n]; // Запись контейнера с наибольшим штрафом } listLenOneFlat.Remove(finalPlacementOneFlat[n]); listLenOneFlat.Remove(finalPlacementOneFlat[n + 1]); if (index1 > index2) { listLenTwoFlat.RemoveAt(index1); listLenTwoFlat.RemoveAt(index2); } else { listLenTwoFlat.RemoveAt(index2); listLenTwoFlat.RemoveAt(index1); } } //приведение длин для конечного отображения for (var k = 0; k < finalPlacementOneFlat.Length; k = k + 2) { var resultAddingPlace = ResultAddingPlace.CalculateAddingPlace(new DataContainer { A1 = finalPlacementOneFlat[k], A2 = finalPlacementOneFlat[k + 1], B1 = finalPlacementTwoFlat[k], B2 = finalPlacementTwoFlat[k + 1] }, 0.3); finalPlacementOneFlat[k] = resultAddingPlace.A1; finalPlacementOneFlat[k + 1] = resultAddingPlace.A2; } return(new ResultGreedyMethode(resultGreedy.Fine, finalPlacementOneFlat.ToList(), finalPlacementTwoFlat.ToList(), resultGreedy.NewFirstOneFlat)); }
//двигаем стены из-за ApartureLength public static DataPerformAlgorithm CreatePlacement(double[] listOneFlat, double[] listTwoFlat, double step) { double[] tempArrayTwoFlat; Array.Copy(listTwoFlat, tempArrayTwoFlat = new double[listTwoFlat.Length], listTwoFlat.Length); var fineCastApartureLen = 0.0; var totalFine = 0.0; double[] totalListOneFlat; Array.Copy(listOneFlat, totalListOneFlat = new double[listOneFlat.Length], listOneFlat.Length); for (var k = 0; k < listTwoFlat.Length; k = k + 2) // Заполнение секций { if (tempArrayTwoFlat[k] - listOneFlat[k] < Constraints.ApartureLength) { var leftAddition = Constraints.ApartureLength - (tempArrayTwoFlat[k] - listOneFlat[k]); if (leftAddition <= step) { tempArrayTwoFlat[k] += Math.Round(step, 1); fineCastApartureLen += Math.Round(step, 1); } else { tempArrayTwoFlat[k] += Math.Round(Math.Ceiling(leftAddition / step) * step, 1); fineCastApartureLen += Math.Round(Math.Ceiling(leftAddition / step) * step, 1); } } if (tempArrayTwoFlat[k + 1] - listOneFlat[k + 1] < Constraints.ApartureLength) { var rightAddition = Constraints.ApartureLength - (tempArrayTwoFlat[k + 1] - listOneFlat[k + 1]); if (rightAddition <= step) { tempArrayTwoFlat[k + 1] += Math.Round(step, 1); fineCastApartureLen += Math.Round(step, 1); } else { tempArrayTwoFlat[k + 1] += Math.Round(Math.Ceiling(rightAddition / step) * step, 1); fineCastApartureLen += Math.Round(Math.Ceiling(rightAddition / step) * step, 1); } } //Приведение площади - отдельный метод var resultAddingPlace = ResultAddingPlace.CalculateAddingPlace(new DataContainer { A1 = listOneFlat[k], A2 = listOneFlat[k + 1], B1 = tempArrayTwoFlat[k], B2 = tempArrayTwoFlat[k + 1] }, step); totalFine += Math.Round(resultAddingPlace.FineContainer, 1); totalListOneFlat[k] = resultAddingPlace.A1; totalListOneFlat[k + 1] = resultAddingPlace.A2; } return(new DataPerformAlgorithm(totalListOneFlat.ToList(), tempArrayTwoFlat.ToList(), Math.Round(totalFine + fineCastApartureLen, 1))); }