Пример #1
0
        public List <double[]> FormScheduleByVectors(double[] targets, List <double[]> fixValues = null)
        {
            if (fixValues == null)
            {
                fixValues = AlgorithmHelper.CreateListOfArrays(_period, _dimension, -1.0);
            }

            if (targets == null || fixValues == null || fixValues.Count() != _period || fixValues.Any(x => x == null))
            {
                throw new ArgumentNullException();
            }
            if (fixValues.Any(x => x.Count() != targets.Count()))
            {
                throw new ArgumentException();
            }

            double[] normTargets = targets.Zip(_maxFlows, (x, y) => x / y).ToArray();

            List <double[]> decompositions = _normRegimesCombinations.Select(x => GetDimensionDecomposition(normTargets, x, _period)).ToList();
            List <double[]> test           = decompositions.Select((x, i) =>
            {
                if (x == null)
                {
                    return(null);
                }
                var vol = _regimesCombinations[i].Zip(x, (comb, decomp) => comb.Select(c => c * decomp).ToArray()).ToList();
                return(AlgorithmHelper.GetSumOnInterval(vol, 0, vol.Count()));
            }).ToList();

            return(null);
        }
Пример #2
0
        public List <double[]> GetSchedule(double[] targets, List <double[]> fixValues = null)
        {
            if (fixValues == null)
            {
                fixValues = AlgorithmHelper.CreateListOfArrays(Period, Dimension, -1.0);
            }

            return(FormSchedule(targets, targets.Select(x => 1.0).ToArray(), fixValues));
        }
Пример #3
0
        public List <double[]> FormScheduleContinuousRegimeField(double[] targets, List <double[]> fixValues = null, int neededPoint = -1)
        {
            if (fixValues == null)
            {
                fixValues = AlgorithmHelper.CreateListOfArrays(_period, _dimension, -1.0);
            }

            List <double[]> result = AlgorithmHelper.CombineIntoList(_algorithms.Select((x, i) => x.FormScheduleContinuousRegimeField(targets[i], fixValues.Select(y => y[i]).ToList(), neededPoint)).ToArray());

            return(result);
        }
Пример #4
0
        public List <double[]> FormSchedule(double[] targets, double[] weights, List <double[]> fixValues = null)
        {
            if (targets == null || weights == null)
            {
                throw new ArgumentNullException();
            }

            // Понижаем объемы по трубе до максимально возможных
            targets = targets.Zip(_maxVolumes, (x, y) => x > y ? y : x).ToArray();

            if (fixValues == null)
            {
                fixValues = AlgorithmHelper.CreateListOfArrays(_period, _dimension, -1.0);
            }

            List <double[]> notSortedSchedule = fixValues.Select(x => x.Select(y => y).ToArray()).ToList();

            for (int i = 0; i < _dimension; i++)
            {
                targets[i] -= fixValues.Sum(x => x[i] < 0 ? 0 : x[i]);
            }
            targets = targets.Select(x => x < 0 ? 0 : x).ToArray();

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Получаем режимы, которыми доступно перекачать данный объем
            //////////////////////////////////////////////////////////////////////////////////////////////////////////

            // Не запланированные объемы перекачки
            double[] currentTarget = targets.Select(x => x).ToArray();
            // Не запланированное время
            int currentPeriod = _period - notSortedSchedule.Count(x => x[0] > 0);

            // Начинаем заполнять интервалы
            for (int idx = 0; idx < _period; idx++)
            {
                if (notSortedSchedule[idx][0] >= 0)
                {
                    continue;
                }

                // Выберем доступные режимы
                List <double[]> strongConstrains = new List <double[]>(),
                                softConstrains   = new List <double[]>();
                bool strong,
                     soft;
                double[] rgm;
                for (int i = 0; i < _avaliableNormRegimesOnIntervals[idx].Count(); i++)
                {
                    soft   = true;
                    strong = true;
                    rgm    = _avaliableNormRegimesOnIntervals[idx][i];
                    for (int j = 0; j < _dimension; j++)
                    {
                        // Если нельзя качать по трубе, а качаем, то режим не подходит
                        if (currentTarget[j] < _minFlows[j] && rgm[j] > 0 && _constraints[j])
                        {
                            soft = false;
                            break;
                        }

                        // Если нужно качать по трубе, но не качаем, то режим не подходит
                        if (strong && currentTarget[j] > _minFlows[j] && rgm[j] == 0)
                        {
                            strong = false;
                        }
                    }

                    if (soft)
                    {
                        softConstrains.Add(rgm);

                        if (strong)
                        {
                            strongConstrains.Add(rgm);
                        }
                    }
                }

                // Выбираем доступные для интервала режимы
                List <double[]> currentAvaliableRegimes = strongConstrains.Count() == 0 ? softConstrains : strongConstrains;

                // Нормированный режим для текущего объема перекачки
                //double[] normTargetRegime = currentTarget.Zip(_maxFlows, (x,y) => x / (currentPeriod * y)).ToArray();
                double[] targetRegime = FormScheduleContinuousRegimeField(targets, notSortedSchedule, idx)[0].Zip(_maxFlows, (x, y) => x / y).ToArray();

                // Ищем ближайший к нему режим среди доступных
                double[] bestRegime = currentAvaliableRegimes[AlgorithmHelper.NearestByDistance(currentAvaliableRegimes, targetRegime)];

                notSortedSchedule[idx] = _regimes[_normRegimes.IndexOf(bestRegime)];

                // Уменьшаем цель
                currentTarget = currentTarget.Zip(notSortedSchedule[idx], (x, y) => x - y).ToArray();

                // Уменьшаем время
                currentPeriod--;
            }

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Расставим полученные режимы (только те, которые не фиксированы)
            //////////////////////////////////////////////////////////////////////////////////////////////////////////

            // Сгруппируем режимы, получим количество каждого режима
            var grouped = notSortedSchedule
                          .Where((x, i) => fixValues[i][0] < 0)
                          .GroupBy(x => x).ToDictionary(x => x.Key, x => x.Count());
            // Получим доступные на интервалах режимы
            List <List <double[]> > avaliableRegimes = _avaliableRegimesOnIntervals.Select(x => x.Where(y => grouped.ContainsKey(y)).ToList()).ToList();

            // Пока просто отсортируем режимы в пределах интервалов с одинаковыми возможными режимами

            // Сгруппируем индексы по списку доступных режимов
            Dictionary <List <double[]>, List <int> > indexesOfSameRegimes = new Dictionary <List <double[]>, List <int> >();

            for (int i = 0; i < _period; i++)
            {
                if (fixValues[i][0] >= 0)
                {
                    continue;
                }

                List <double[]> cur = avaliableRegimes[i];
                List <double[]> key = null;
                foreach (var el in indexesOfSameRegimes)
                {
                    if (AlgorithmHelper.ListsEqualityNoOrder(cur, el.Key))
                    {
                        key = el.Key;
                        break;
                    }
                }
                if (key == null)
                {
                    indexesOfSameRegimes.Add(cur, new List <int>());
                    key = cur;
                }

                indexesOfSameRegimes[key].Add(i);
            }

            // Сортируем в пределах возможных интервалов (по дистанции между режимами и координатой (0,...,0) )

            List <double[]> sortedSchedule = fixValues.Select(x => x.Select(y => y).ToArray()).ToList();

            foreach (var el in indexesOfSameRegimes)
            {
                List <double[]> forSort = el.Value.Select((x) => _normRegimes[_regimes.IndexOf(notSortedSchedule[x])]).ToList();
                forSort.Sort((x, y) =>
                {
                    double dx = AlgorithmHelper.GetLength(x), dy = AlgorithmHelper.GetLength(y);

                    if (dx == dy)
                    {
                        return(0);
                    }
                    else if (dx > dy)
                    {
                        return(-1);
                    }
                    else
                    {
                        return(1);
                    }
                });
                for (int i = 0; i < el.Value.Count(); i++)
                {
                    sortedSchedule[el.Value[i]] = _regimes[_normRegimes.IndexOf(forSort[i])].Select(x => x).ToArray();
                }
            }

            return(sortedSchedule);
        }
        public List<List<double[]>> Balance(Action<string> informationAction = null)
        {
            if (informationAction == null)
                informationAction = (str) => { };

            List<List<double[]>> initialSchedules = null;
            List<double> prevOverfillVolumes = new List<double>();

            List<List<double[]>> ConvertResult()
            {
                if (_sections[0] == null)
                    initialSchedules.RemoveAt(0);
                else if (_sections.Last() == null)
                    initialSchedules.RemoveAt(initialSchedules.Count() - 1);
                return initialSchedules;
            }
            void CalcInitialSchedules()
            {
                initialSchedules = _tempSolutions.Select((x, i) =>
                {
                    if (_sections[i] == null)
                        return AlgorithmHelper.CreateListOfArrays(_period, 1, 0.0);
                    else
                        return _sections[i].GetFullSchedule(CreateInitialSchedule(x));
                }).ToList();
            }
            void CalcOverfill()
            {
                prevOverfillVolumes = new List<double>();
                for (int i = 0; i < initialSchedules.Count() - 1; i++)
                {
                    var reservoirSchedule = GetReservoirSchedule(initialSchedules[i], initialSchedules[i + 1], _tempPumpSchedules[i], _oilStartVolumes[i]);
                    prevOverfillVolumes.Add(GetOverfillVolume(reservoirSchedule, 0, _reservoirVolumes[i]));
                }
            }

            // Сначала без анализа и перестановок
            CreateTempSolution();
            CalcInitialSchedules();
            CalcOverfill();
            if (prevOverfillVolumes.All(x => x == 0.0))
            {
                return ConvertResult();
            }

            int maxIter = 1;
            for (int i = 0; i < maxIter; i++)
            {
                // Перестановки
                CreateTempSolution();
                CalcInitialSchedules();
                initialSchedules = Permute(initialSchedules, 24, 100, informationAction);

                CalcOverfill();
                if (prevOverfillVolumes.All(x => x == 0.0))
                {
                    return ConvertResult();
                }

                // Анализ и изменение объемов
                if (!Analyse(initialSchedules))
                    break;

                CreateTempSolution();
                CalcInitialSchedules();
                CalcOverfill();
                if (prevOverfillVolumes.All(x => x == 0.0))
                {
                    return ConvertResult();
                }
            }

            if (initialSchedules == null)
                return null;
            else
                return ConvertResult();
        }