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