public void CalculateNode() { lock (edgeLocker) { if (IsCalculated) { return; } List <double[]> inSchedule, outSchedule, inFixValues = AH.CreateListOfArrays(start.algorithm._period, start.algorithm._inDimension, -1.0), outFixValues = AH.CreateListOfArrays(start.algorithm._period, start.algorithm._outDimension, -1.0); for (int i = 0; i < start.crashIndex - 1; i++) { inFixValues[i] = start.inSchedule[i].Select(x => x).ToArray(); outFixValues[i] = start.outSchedule[i].Select(x => x).ToArray(); } for (int i = start.crashIndex - 1; i < workTime; i++) { inFixValues[i] = regimesPair.Item1.Select(x => x).ToArray(); outFixValues[i] = regimesPair.Item2.Select(x => x).ToArray(); } inSchedule = start.algorithm._inAlgorithm.GetSchedule(start.initVals.inTargets, inFixValues); outSchedule = start.algorithm._outAlgorithm.GetSchedule(start.initVals.outTargets, outFixValues); end = new GreedyNode(inSchedule, outSchedule, start.algorithm, start.initVals); end.inputEdge = this; IsCalculated = true; } }
public GreedyEdge GetRandomEdge() { lock (nodeLocker) { if (edgesList.Count() == 0) { return(null); } int pairIndex = AH.GetRouletIndex(pairProbabilities); int timeIndex = AH.RandomInstance.Next(0, edgesCountForPair[pairIndex]); return(edgesList.Where(x => x.regimesPair == avaliablePairs[pairIndex]).ToList()[timeIndex]); } }
public Tuple <List <double[]>, List <double[]> > FormSchedule(ref InitialValues initVals, Action <string> action = null) { List <double[]> inFixValues = AH.CreateListOfArrays(_period, _inDimension, -1.0), outFixValues = AH.CreateListOfArrays(_period, _outDimension, -1.0), inSchedule = _inAlgorithm.GetSchedule(initVals.inTargets, inFixValues), outSchedule = _outAlgorithm.GetSchedule(initVals.outTargets, outFixValues); DiscreteSchedule reservoirSchedule = GetReservoirSchedule(inSchedule, outSchedule, initVals.startVolume, initVals.pumpsSchedule); int idx = reservoirSchedule.FirstIndexOfOutOfRange(initVals.minVolume, initVals.maxVolume); if (idx == -1) { return(new Tuple <List <double[]>, List <double[]> >(inSchedule, outSchedule)); } List <Tuple <List <double[]>, List <double[]> > > schedules; switch (initVals.algorithmType) { case AlgorithmType.GRAPH: schedules = GreedyRandomizeSearch(ref initVals, inSchedule, outSchedule, action); break; default: schedules = new List <Tuple <List <double[]>, List <double[]> > >() { DinamicProgramming(initVals, action) }; break; } action("Выбираем оптимальное на основе критериев"); if (schedules.Count() == 0) { return(null); } else if (schedules.Count() == 1) { return(schedules[0]); } else { List <double> criterias = GetCriteria(initVals.inTargets, initVals.outTargets, schedules); var best = schedules[criterias.IndexOf(criterias.Min())]; return(best); } }
public ReservoirBalanceAlgorithm(TechnologicalSectionAlgorithm inAlgorithm, TechnologicalSectionAlgorithm outAlgorithm, double bufferVolume, Tuple <int, int> connection, Tuple <bool[], bool[]> constraints) { _inAlgorithm = inAlgorithm; _outAlgorithm = outAlgorithm; _period = _inAlgorithm.Period; _inDimension = _inAlgorithm.Dimension; _outDimension = _outAlgorithm.Dimension; _connection = connection; _constraints = constraints; _bufferVolume = bufferVolume; _regimesPairs = AH.CartesianProduct(new List <List <double[]> >() { _inAlgorithm.Regimes, _outAlgorithm.Regimes }).Select(x => new Tuple <double[], double[]>(x.First(), x.Last())).ToList(); _normRegimesPairs = AH.CartesianProduct(new List <List <double[]> >() { _inAlgorithm.NormRegimes, _outAlgorithm.NormRegimes }).Select(x => new Tuple <double[], double[]>(x.First(), x.Last())).ToList(); _reservoirDifferences = _regimesPairs.Select(x => x.Item1[_connection.Item1] - x.Item2[_connection.Item2]).ToList(); _pairsDifferences = new List <List <double> >(); int num = _regimesPairs.Count(); for (int i = 0; i < num; i++) { List <double> l = new List <double>(); _pairsDifferences.Add(l); for (int j = 0; j < num; j++) { l.Add(GetRegimesDifference(_normRegimesPairs[i], _normRegimesPairs[j])); } } _avaliablePairsOnIntervals = new List <List <Tuple <double[], double[]> > >(); for (int i = 0; i < _period; i++) { _avaliablePairsOnIntervals.Add(_regimesPairs.Where(x => IsRegimeAvaliable(x, i)).ToList()); } }
private double GetRegimesDifference(Tuple <double[], double[]> p1, Tuple <double[], double[]> p2) { return(AH.GetDistance(p1.Item1.Concat(p1.Item2).ToArray(), p2.Item1.Concat(p2.Item2).ToArray())); }
private List <double> GetCriteria(double[] inTargets, double[] outTargets, List <Tuple <List <double[]>, List <double[]> > > schedules) { List <double> changesCriteria = AH.CreateListOfElements(schedules.Count(), 0.0), differenceCriteria = AH.CreateListOfElements(schedules.Count(), 0.0); Parallel.For(0, schedules.Count(), (scheduleNumber) => { var schedule = schedules[scheduleNumber]; int cangeCount = 0; List <double[]> s1 = schedule.Item1, s2 = schedule.Item2; for (int i = 1; i < _period; i++) { if (!s1[i].SequenceEqual(s1[i - 1])) { cangeCount++; } if (!s2[i].SequenceEqual(s2[i - 1])) { cangeCount++; } } changesCriteria[scheduleNumber] = cangeCount; double[] sum = AH.GetSumOnInterval(schedule.Item1, 0, _period).Concat(AH.GetSumOnInterval(schedule.Item2, 0, _period).ToArray()).ToArray(); double[] dif = AH.GetDifOfVectors(sum, inTargets.Concat(outTargets).ToArray()); double[] maxDif = AH.GetSumOnInterval(_inAlgorithm.UpperBounds, 0, _period).Concat(AH.GetSumOnInterval(_outAlgorithm.UpperBounds, 0, _period)).ToArray(); dif = dif.Zip(maxDif, (x, y) => x / y).ToArray(); differenceCriteria[scheduleNumber] = dif.Sum() / dif.Count(); }); changesCriteria = changesCriteria.Select(x => x / (_period * 2)).ToList(); //List<double> differenceCriteria = sumDif.Select(x => x.Sum() / x.Count()).ToList(); //// Суммы перекачанной нефти //List<Tuple<double[], double[]>> sum = schedules.Select((x) => // new Tuple<double[], double[]>( AH.GetSumOnInterval(x.Item1, 0, _period), AH.GetSumOnInterval(x.Item2, 0, _period))).ToList(); //// Отличие перекачки от целей (по модулю) //List<double[]> sumDif = sum.Select((x) => //{ // double[] inDif = AH.GetDifOfVectors(x.Item1, inTargets), // outDif = AH.GetDifOfVectors(x.Item2, outTargets); // return inDif.Concat(outDif).Select(Math.Abs).ToArray(); //}).ToList(); //// Нормализуем отличия //// sumDif = AH.NormalizeByComponents(sumDif); //double[] maxSum = AH.GetSumOnInterval(_inAlgorithm.UpperBounds, 0, _period).Concat(AH.GetSumOnInterval(_outAlgorithm.UpperBounds, 0, _period)).ToArray(); //sumDif = sumDif.Select(x => x.Zip(maxSum, (y, yMax) => y / yMax).ToArray()).ToList(); //// КРИТЕРИЙ: отличие от целей //List<double> differenceCriteria = sumDif.Select(x => x.Sum() / x.Count()).ToList(); ////differenceCriteria = AH.NormalizeList(differenceCriteria); //// Сумма отличий на каждом интервале от среднего по модулю //List<double[]> difModulSum = schedules.Select((x,i) => //{ // // Получим средние расписания // List<double[]> inAvgSchedule = _inAlgorithm.GetContinuousSchedule(sum[i].Item1), // outAvgSchedule = _outAlgorithm.GetContinuousSchedule(sum[i].Item2); // // Вычислим отклонения // List<double[]> inDeviationsByModul = AH.GetDeviations(x.Item1, inAvgSchedule).Select(y => y.Select(Math.Abs).ToArray()).ToList(), // outDeviationsByModul = AH.GetDeviations(x.Item2, outAvgSchedule).Select(y => y.Select(Math.Abs).ToArray()).ToList(); // return AH.GetSumOnInterval(inDeviationsByModul, 0, _period).Concat(AH.GetSumOnInterval(outDeviationsByModul, 0, _period)).ToArray(); //}).ToList(); //// Нормализуем ////difModulSum = AH.NormalizeByComponents(difModulSum); //difModulSum = difModulSum.Select(x => x.Zip(maxSum, (y, yMax) => y / yMax).ToArray()).ToList(); //// КРИТЕРИЙ: Неравномерность //List<double> uniformityCriteria = difModulSum.Select(x => x.Sum() / x.Count()).ToList(); ////uniformityCriteria = AH.NormalizeList(uniformityCriteria); return(schedules.Select((x, i) => 0.0 * changesCriteria[i] + 1.0 * differenceCriteria[i]).ToList()); }
public void CalculateEdges() { lock (nodeLocker) { if (IsCalculated) { return; } // Отбираем режимы double[] beforeCrashInVolumes = AH.GetSumOnInterval(inSchedule, 0, crashIndex - 1), beforeCrashOutVolumes = AH.GetSumOnInterval(outSchedule, 0, crashIndex - 1); avaliablePairs = algorithm._avaliablePairsOnIntervals[crashIndex - 1]; List <int> timesOfAvaliability = avaliablePairs.Select(pair => { int start = crashIndex - 1; double resVol = reservoirSchedule[start]; double[] curInVolumes = beforeCrashInVolumes.Select(x => x).ToArray(), curOutVolumes = beforeCrashOutVolumes.Select(x => x).ToArray(); double difference = algorithm._reservoirDifferences[algorithm._regimesPairs.IndexOf(pair)]; for (int i = start; i < algorithm._period; i++) { if (algorithm._avaliablePairsOnIntervals[i].IndexOf(pair) == -1) { return(i); } resVol += (difference + initVals.pumpsSchedule[i]); if (resVol < initVals.minVolume || resVol > initVals.maxVolume) { return(i); } curInVolumes = curInVolumes.Zip(pair.Item1, (x, y) => x + y).ToArray(); for (int j = 0; j < algorithm._inDimension; j++) { if (algorithm._constraints.Item1[j] && initVals.inTargets[j] < curInVolumes[j]) { return(i); } } curOutVolumes = curOutVolumes.Zip(pair.Item2, (x, y) => x + y).ToArray(); for (int j = 0; j < algorithm._outDimension; j++) { if (algorithm._constraints.Item2[j] && initVals.outTargets[j] < curOutVolumes[j]) { return(i); } } } return(algorithm._period); }).ToList(); avaliablePairs = avaliablePairs.Where((x, i) => timesOfAvaliability[i] == algorithm._period || timesOfAvaliability[i] - crashIndex + 1 >= algorithm.MINIMUM_WORK_TIME).ToList(); timesOfAvaliability = timesOfAvaliability.Where(x => x == algorithm._period || x - crashIndex + 1 >= algorithm.MINIMUM_WORK_TIME).ToList(); if (avaliablePairs.Count() > 0) { // Вычисляем вероятности Tuple <double[], double[]> currentPair = algorithm._regimesPairs.First(x => x.Item1.SequenceEqual(inSchedule[crashIndex - 1]) && x.Item2.SequenceEqual(outSchedule[crashIndex - 1])); int currentIdx = algorithm._regimesPairs.IndexOf(currentPair); pairProbabilities = avaliablePairs.Select((x) => { int r1 = algorithm._regimesPairs.IndexOf(x); return(1 / (algorithm._pairsDifferences[currentIdx][r1] + 0.1)); }).ToList(); pairProbabilities = pairProbabilities.Select(x => x / pairProbabilities.Sum()).ToList(); // Делаем временную сетку for (int i = 0; i < avaliablePairs.Count(); i++) { int minT = Math.Min(algorithm._period, crashIndex - 1 + algorithm.MINIMUM_WORK_TIME), maxT = timesOfAvaliability[i]; Tuple <double[], double[]> p = avaliablePairs[i]; List <int> times = AH.GetGridOnInterval(minT, maxT, gridSize); if (times.Count() > 1) { times.RemoveAt(0); } edgesCountForPair.Add(times.Count()); times.ForEach(x => edgesList.Add(new GreedyEdge(this, avaliablePairs[i], x))); } } reservoirSchedule = null; IsCalculated = true; } }