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); }
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)); }
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); }
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(); }