예제 #1
0
        /// <summary>
        ///     Отсечение лишних квартир. Два правила:
        ///         а) Количество квартир на этажах одинаковое
        ///         б) Площадь секции не превышает 500м2
        ///     Стараемся отбрасывать самые маленькие однокомнатные, так как их проще встроить в новую модель.
        ///     Алгоритм в лоб:
        ///         Сначала работаем с правилом б. Отсекаем лишние
        ///         Проверяем на выполнение правила а
        /// </summary>
        public static Building ToSeverExcessFlats(Building building)
        {
            // Общая нежилая площадь = Лестничная клетка + коридор
            var generalSquare = Math.Round(Constraints.EntrywayLength * Constraints.WidthFlat[4] + Constraints.MaxSquareCorridor, 2);

            building.Flats = building.Flats.OrderBy(a => a.InputSquare).ToList();

            var listSquares = Flat.ReceiveListCastSquares(building.Flats);

            // Суммарная допустимая жилая площадь
            var livingSquare = (Constraints.MaxSquareSection - generalSquare) * building.CountFloor;
            var k            = listSquares.Sum();

            //б)
            while (listSquares.Sum() > livingSquare)
            {
                building.FlatsExcess.Add(building.Flats.First());
                building.Flats.Remove(building.Flats.First());
                listSquares.Remove(listSquares.First());
            }
            //а)
            while (building.Flats.Count % building.CountFloor != 0)
            {
                building.FlatsExcess.Add(building.Flats.First());
                building.Flats.Remove(building.Flats.First());
            }
            return(building);
        }
예제 #2
0
        /// <summary>
        ///     Определим правильную группировку. Для этого рассмотрим 3 варианта:
        ///         а) Привести все к одному виду
        ///         б) Привести все, кроме одной, к одному виду
        ///         в) Привести все, кроме двух, к одному виду
        ///     Придумать веса для выбора варианта. Среди вариантов б и в выигрывает с меньшим штрафом. А как сравнить с вариантом а?
        ///     Вводим коэффициент 2% для варианта а. Если выгода от других вариантов меньше 2%, то не стоит даже запариваться.
        /// </summary>
        public static List <Flat> ToGroupBiggerFlats(List <Flat> listExcessFlats)
        {
            listExcessFlats = listExcessFlats.OrderBy(a => a.CastSquare).ToList();
            var list = Flat.ReceiveListCastSquares(listExcessFlats);
            //определение правильной группировки
            var strategyOfGrouping = new Dictionary <char, double>
            {
                ['A'] = list.Last() * list.Count * 0.95,
                ['B'] = list.Last() + list[list.Count - 2] * (list.Count - 1),
                ['C'] = list.Last() * 2 + list[list.Count - 3] * (list.Count - 2)
            };
            //Вычисление максимального
            var max   = listExcessFlats.Last().CastSquare;
            var max_1 = listExcessFlats[listExcessFlats.Count - 2].CastSquare;
            var max_2 = listExcessFlats[listExcessFlats.Count - 3].CastSquare;

            switch (strategyOfGrouping.OrderBy(a => a.Value).First().Key)
            {
            case 'A':
                foreach (var elem in listExcessFlats)
                {
                    elem.Fine      += Math.Round(max - elem.CastSquare, 2);
                    elem.CastSquare = max;
                }
                break;

            case 'B':
                //группа без самой большой
                for (var i = 0; i < listExcessFlats.Count - 1; i++)
                {
                    listExcessFlats[i].Fine      += Math.Round(max_1 - listExcessFlats[i].CastSquare, 2);
                    listExcessFlats[i].CastSquare = max_1;
                }
                break;

            case 'C':
                //первая группа
                for (var i = 0; i < listExcessFlats.Count - 2; i++)
                {
                    listExcessFlats[i].Fine      += Math.Round(max_2 - listExcessFlats[i].CastSquare, 2);
                    listExcessFlats[i].CastSquare = max_2;
                }
                //вторая группа
                for (var i = listExcessFlats.Count - 2; i < listExcessFlats.Count; i++)
                {
                    listExcessFlats[i].Fine      += Math.Round(max - listExcessFlats[i].CastSquare, 2);
                    listExcessFlats[i].CastSquare = max;
                }
                break;
            }
            return(listExcessFlats);
        }