コード例 #1
0
        public DiscreteSchedule GetReverse()
        {
            DiscreteSchedule result = new DiscreteSchedule(this);

            result._schedule.Reverse();
            return(result);
        }
コード例 #2
0
        public DiscreteSchedule(DiscreteSchedule p)
        {
            if (p == null)
            {
                throw new ArgumentNullException();
            }

            _schedule = p._schedule.Clone() as double[];
        }
コード例 #3
0
        public DiscreteSchedule GetIntegral()
        {
            DiscreteSchedule result = new DiscreteSchedule(this);

            for (int i = 1; i < result.Size; i++)
            {
                result[i] = result[i] + result[i - 1];
            }

            return(result);
        }
コード例 #4
0
        public DiscreteSchedule GetReverseIntegral()
        {
            DiscreteSchedule result = new DiscreteSchedule(this);

            for (int i = result.Size - 2; i >= 0; i--)
            {
                result[i] = result[i] + result[i + 1];
            }

            return(result);
        }
コード例 #5
0
        private DiscreteSchedule GetReservoirSchedule(List <double[]> inSchedule, List <double[]> outSchedule, double startVolume, List <double> pumpsSchedule)
        {
            DiscreteSchedule result = new DiscreteSchedule(_period + 1, 0);

            result[0] = startVolume;
            for (int i = 1; i < _period + 1; i++)
            {
                result[i] = result[i - 1] + inSchedule[i - 1][_connection.Item1] - outSchedule[i - 1][_connection.Item2] + pumpsSchedule[i - 1];
            }
            return(result);
        }
コード例 #6
0
        /// <summary>
        /// Перекрытие поменшему значению
        /// </summary>
        /// <param name="p2"></param>
        /// <returns></returns>
        public DiscreteSchedule Overlap(DiscreteSchedule p2)
        {
            DiscreteSchedule result = new DiscreteSchedule(Size);

            for (int i = 0; i < Size; i++)
            {
                result[i] = _schedule[i] < p2._schedule[i] ? _schedule[i] : p2._schedule[i];
            }

            return(result);
        }
コード例 #7
0
        public DiscreteSchedule GetPart(int startIndex, int endIndex = -1)
        {
            CheckInterval(startIndex, ref endIndex);

            DiscreteSchedule result = new DiscreteSchedule(endIndex - startIndex);

            for (int i = startIndex; i < endIndex; i++)
            {
                result[i - startIndex] = _schedule[i];
            }
            return(result);
        }
コード例 #8
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);
            }
        }
コード例 #9
0
        /// <summary>
        /// Линейная комбинация расписаний где каждый элемент нового расписания равен p1+k*p2
        /// </summary>
        /// <param name="p1">Первое расписание</param>
        /// <param name="p2">Второе расписание</param>
        /// <param name="k">Коэффициент</param>
        /// <returns>Линейная комбинация расписаний</returns>
        public static DiscreteSchedule Combine(DiscreteSchedule p1, DiscreteSchedule p2, int k)
        {
            if (p1 == null || p2 == null)
            {
                throw new ArgumentNullException();
            }

            if (p1.Size != p2.Size)
            {
                throw new ArgumentException("Не совпадают размеры расписаний");
            }

            DiscreteSchedule result = new DiscreteSchedule();

            result._schedule = p1._schedule.Zip(p2._schedule, (x, y) => x + k * y).ToArray();

            return(result);
        }
コード例 #10
0
            public GreedyNode(List <double[]> inSchedule, List <double[]> outSchedule, ReservoirBalanceAlgorithm algorithm, InitialValues initVals)
            {
                this.inSchedule  = inSchedule;
                this.outSchedule = outSchedule;
                this.initVals    = initVals;
                this.algorithm   = algorithm;

                reservoirSchedule = algorithm.GetReservoirSchedule(inSchedule, outSchedule, initVals.startVolume, initVals.pumpsSchedule);
                crashIndex        = reservoirSchedule.FirstIndexOfOutOfRange(initVals.minVolume, initVals.maxVolume);

                if (crashIndex != -1)
                {
                    sign = reservoirSchedule[crashIndex] > initVals.maxVolume ? -1 : 1;
                }

                IsCalculated   = false;
                IsFullExplored = false;
            }
コード例 #11
0
        /// <summary>
        /// Разбивает каждый интервал расписания на k элементов
        /// </summary>
        /// <param name="k">Количество элементов, на которые разбивается каждый элемент расписания</param>
        /// <returns>Дискретизированное расписание</returns>
        public DiscreteSchedule Split(int k)
        {
            if (k < 2)
            {
                throw new ArgumentOutOfRangeException("Нельзя разделить меньше чем на 2 части");
            }

            DiscreteSchedule result = new DiscreteSchedule(Size * k);

            for (int i = 0; i < Size; i++)
            {
                for (int j = 0; j < k; j++)
                {
                    result._schedule[i * k + j] = _schedule[i] / k;
                }
            }

            return(result);
        }
コード例 #12
0
        /// <summary>
        /// Объединяет каждые k элементов в расписании
        /// </summary>
        /// <param name="k">Количество объединияемых подряд элементов</param>
        /// <returns>Новое расписание с объединенными интервалами</returns>
        public DiscreteSchedule UnSplit(int k)
        {
            if (k < 2)
            {
                throw new ArgumentOutOfRangeException("Нельзя объединять больше чем 2 части");
            }
            if (Size % k != 0)
            {
                throw new ArgumentException("Размер расписания не кратен величине объединения");
            }

            DiscreteSchedule result = new DiscreteSchedule(Size / k);

            for (int i = 0; i < Size; i++)
            {
                result._schedule[i / k] += _schedule[i];
            }

            return(result);
        }
コード例 #13
0
        public static DiscreteSchedule GetDiffereceIntegral(double startValue, DiscreteSchedule p1, DiscreteSchedule p2)
        {
            if (p1 == null | p2 == null)
            {
                throw new ArgumentNullException();
            }
            if (p1.Size != p2.Size)
            {
                throw new ArgumentException();
            }

            DiscreteSchedule result = new DiscreteSchedule(p1.Size + 1);

            result[0] = startValue;
            for (int i = 1; i < result.Size; i++)
            {
                result[i] = result[i - 1] + p1[i - 1] - p2[i - 1];
            }

            return(result);
        }
コード例 #14
0
 public static DiscreteSchedule GetDiffereceIntegral(double startValue, List <double> p1, List <double> p2)
 {
     return(DiscreteSchedule.GetDiffereceIntegral(startValue, new DiscreteSchedule(p1.ToArray()), new DiscreteSchedule(p2.ToArray())));
 }
コード例 #15
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;
                }
            }