示例#1
0
            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;
                }
            }
示例#2
0
            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]);
                }
            }
示例#3
0
        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);
            }
        }
示例#4
0
        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());
            }
        }
示例#5
0
 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()));
 }
示例#6
0
        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());
        }
示例#7
0
            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;
                }
            }