コード例 #1
0
        static void Main(string[] args)
        {
            //На входе: минимальная температура tMin
            var tMin = 0.0001d;
            //начальная температура tInitial
            var tInitial = 1d;

            //Е - функция оптимизации - чем она меньше, тем состояние более оптимально
            var optimizationFunction = new OptimizationFunction(state =>
            {
                var servers = state.Servers;

                var freeServersTerm     = servers.Count(x => x.IsFree) * 2.5;
                var negativeHddFreeTerm = servers.Where(x => x.HddFree < 0).Select(x => x.HddFree * 3).Sum();
                var positiveHddFreeTerm = servers.Where(x => x.HddFree > 0).Select(x => x.HddFree * 0.2).Sum();
                var negativeRamFreeTerm = servers.Where(x => x.RamFree < 0).Select(x => x.RamFree * 3).Sum();
                var positiveRamFreeTerm = servers.Where(x => x.RamFree > 0).Select(x => x.RamFree * 0.2).Sum();
                var negativeCpuFreeTerm = servers.Where(x => x.CpuFree < 0).Select(x => x.CpuFree * 3).Sum();
                var positiveCpuFreeTerm = servers.Where(x => x.CpuFree > 0).Select(x => x.CpuFree * 0.2).Sum();

                var fitness = freeServersTerm + negativeHddFreeTerm + positiveHddFreeTerm + negativeRamFreeTerm +
                              positiveRamFreeTerm + negativeCpuFreeTerm + positiveCpuFreeTerm;

                //по каждому серверу нужно вычислить коэффициент заполненности
                var serversFill = new List <double>();
                foreach (var server in servers)
                {
                    var serverFill = ((server.HddFull - server.HddFree) / server.HddFull) * 0.2 +
                                     ((server.RamFull - server.RamFree) / server.RamFull) * 0.4 +
                                     ((server.CpuFull - server.CpuFree) / server.CpuFull) * 0.4;
                    serversFill.Add(serverFill);
                }
                serversFill = serversFill.OrderByDescending(x => x).ToList();
                //отладочная строка
                //var serversFill = new List<double> { 0.9d, 0.9d, 0.6d, 0.2d,0 };
                //среднее значение заполненности серверов
                var averageFill = serversFill.Sum() / servers.Count();
                //рассчитаем дисперсию у serversFill
                var dispersion = serversFill.Select(eachFill => (eachFill - averageFill) * (eachFill - averageFill)).Sum() / servers.Count;

                return(-(dispersion * 3) - fitness);
            });
            //Т - функция изменения температуры (понижения температуры)
            var decreaseTemperatureFunction = new DecreaseTemperatureFunction((initialTemp, i) =>
            {
                return(initialTemp * 0.1 / i);
            });

            //F - функция, порождающая новое состояние
            //за порождение нового состояния отвечает класс State, метод GetMutatedState


            //Задаём произвольное первое состояние нашей инфраструктуры state1
            TestData.GetData(out var servers, out var services);
            //Выполняем алгоритм
            PerformAnnealing(tInitial, tMin, optimizationFunction,
                             decreaseTemperatureFunction, servers, services);
        }
コード例 #2
0
        private static void PerformAnnealing(double tInitial,
                                             double tMin,
                                             OptimizationFunction optimizationFunction,
                                             DecreaseTemperatureFunction decreaseTemperatureFunction,
                                             IList <Server> servers, IList <Service> services)
        {
            var stopwatch = new Stopwatch();

            stopwatch.Start();

            var currentState = new State(servers, services);

            currentState.Initialize();
            //считаем значение функции оптимизации E от первоначального состояния
            var e = optimizationFunction.Evaluate(currentState);

            var currentTemperature = tInitial;
            var iterationNumber    = 1;

            while (currentTemperature > tMin)
            {
                //получить новое, немного измененное состояние (немного измененное распределение серверов)
                var newState = currentState.GetMutatedState(currentState);
                //посчитать разницу значений функции оптимизации
                var deltaE = optimizationFunction.Evaluate(newState) - optimizationFunction.Evaluate(currentState);
                //если значение функции оптимизации меньше или равно нулю, то осуществляем переход на новое состояние
                if (deltaE <= 0)
                {
                    currentState = newState;
                }
                //иначе, осуществляем переход на новое состояние с вероятностью jumpProbability
                {
                    var jumpProbability = TransitionProbability.Evaluate(deltaE, currentTemperature);
                    var randNumber      = new Random().NextDouble();
                    if (randNumber <= jumpProbability)
                    {
                        currentState = newState;
                    }
                }
                //понижаем температуру
                currentTemperature = decreaseTemperatureFunction.Evaluate(tInitial, iterationNumber);
                iterationNumber++;
            }
            stopwatch.Stop();
            ShowResult(currentState, services, optimizationFunction.Evaluate(currentState), stopwatch.Elapsed);
        }