Пример #1
0
        public double[] Solve(IProblem problem)
        {
            Random rnd = new Random();

            Nest[]   hosts = new Nest[NumberOfNests];
            double[] bestGlobalPosition = new double[problem.Dimension];

            // generate initial population of host nests
            for (int i = 0; i < hosts.Length; i++)
            {
                double[] randomPosition = new double[problem.Dimension];
                for (int j = 0; j < randomPosition.Length; j++)
                {
                    randomPosition[j] = (problem.MaxX - problem.MinX) * rnd.NextDouble() + problem.MinX;
                }

                double error = problem.ErrorFunction(randomPosition);

                hosts[i] = new Nest(randomPosition, error);
            }


            int currentIteration = 0;

            while (currentIteration < MaxIterations)
            {
                for (int i = 0; i < hosts.Length; i++)
                {
                    double[] newCoords = new double[problem.Dimension];
                    hosts[i].Coords.CopyTo(newCoords, 0);
                    for (int j = 0; j < problem.Dimension; j++)
                    {
                        newCoords[j] += LevyFlight(LevyExponent);
                        if (newCoords[j] < problem.MinX)      // new position out of min-bound
                        {
                            newCoords[j] = problem.MinX;
                        }
                        if (newCoords[j] > problem.MaxX)      // new position out of max-bound
                        {
                            newCoords[j] = problem.MaxX;
                        }
                    }
                    double error   = problem.ErrorFunction(newCoords);
                    Nest   newNest = new Nest(newCoords, error);

                    if (newNest.Error < hosts[i].Error)
                    {
                        newNest.Coords.CopyTo(hosts[i].Coords, 0);
                        hosts[i].Error = newNest.Error;
                    }
                }

                Array.Sort(hosts);
                for (int i = hosts.Length - 1; i > 1; i--)
                {
                    int abandon = rnd.Next(0, 100);
                    if (abandon < ProbabilityOfAbandon)
                    {
                        double[] randomPosition = new double[problem.Dimension];
                        for (int j = 0; j < randomPosition.Length; j++)
                        {
                            randomPosition[j] = (problem.MaxX - problem.MinX) * rnd.NextDouble() + problem.MinX;
                        }

                        double error = problem.ErrorFunction(randomPosition);
                        hosts[i] = new Nest(randomPosition, error);
                    }
                }
                Array.Sort(hosts);

                hosts[0].Coords.CopyTo(bestGlobalPosition, 0);
                if (hosts[0].Error < AcceptableError)
                {
                    break;
                }

                currentIteration++;
            }
            return(bestGlobalPosition);
        }
        public double[] Solve(IProblem problem)
        {
            Random rnd = new Random();

            Particle[] swarm = new Particle[NumberOfParticles];
            double[]   bestGlobalPosition = new double[problem.Dimension]; // best solution found by any particle in the swarm
            double     bestGlobalError    = double.MaxValue;

            // init swarm
            for (int i = 0; i < swarm.Length; i++)
            {
                double[] randomPosition = new double[problem.Dimension];
                for (int j = 0; j < randomPosition.Length; j++)
                {
                    randomPosition[j] = (problem.MaxX - problem.MinX) * rnd.NextDouble() + problem.MinX;
                }

                double   error          = problem.ErrorFunction(randomPosition);
                double[] randomVelocity = new double[problem.Dimension];

                for (int j = 0; j < randomVelocity.Length; j++)
                {
                    double low  = problem.MinX * 0.1;
                    double high = problem.MaxX * 0.1;
                    randomVelocity[j] = (high - low) * rnd.NextDouble() + low;
                }
                swarm[i] = new Particle(randomPosition, error, randomVelocity, randomPosition, error);

                if (swarm[i].Error < bestGlobalError)
                {
                    bestGlobalError = swarm[i].Error;
                    swarm[i].Coords.CopyTo(bestGlobalPosition, 0);
                }
            }

            double inertia = 0.729;           // inertia weight
            double localWeight = 1.49445;     // local weight
            double globalWeight = 1.49445;    // global weight
            double localRandom, globalRandom; // local and global weights randomizations
            double probabilityOfDeath     = 0.01;
            int    currentIteration       = 0;
            bool   acceptableErrorReached = false;

            double[] newVelocity = new double[problem.Dimension];
            double[] newPosition = new double[problem.Dimension];
            double   newError;

            while (currentIteration < MaxIterations && !acceptableErrorReached)
            {
                foreach (Particle currentParticle in swarm)
                {
                    // calculate new velocity (displacement of the particle)
                    for (int i = 0; i < currentParticle.Velocity.Length; i++)
                    {
                        localRandom  = rnd.NextDouble();
                        globalRandom = rnd.NextDouble();

                        newVelocity[i] = (inertia * currentParticle.Velocity[i]) +
                                         (localWeight * localRandom * (currentParticle.BestPosition[i] - currentParticle.Coords[i])) +
                                         (globalWeight * globalRandom * (bestGlobalPosition[i] - currentParticle.Coords[i]));
                    }
                    newVelocity.CopyTo(currentParticle.Velocity, 0);

                    // calculate new position after displacement
                    for (int i = 0; i < currentParticle.Coords.Length; i++)
                    {
                        newPosition[i] = currentParticle.Coords[i] + newVelocity[i];
                        if (newPosition[i] < problem.MinX)      // new position out of min-bound
                        {
                            newPosition[i] = problem.MinX;
                        }
                        if (newPosition[i] > problem.MaxX)      // new position out of max-bound
                        {
                            newPosition[i] = problem.MaxX;
                        }
                    }
                    newPosition.CopyTo(currentParticle.Coords, 0);

                    // evaluate the error with the new params
                    newError = problem.ErrorFunction(newPosition);
                    currentParticle.Error = newError;

                    if (newError < currentParticle.BestError)    // is newPosition a local best
                    {
                        newPosition.CopyTo(currentParticle.BestPosition, 0);
                        currentParticle.BestError = newError;
                    }
                    if (newError < bestGlobalError)              // is newPosition a global best
                    {
                        newPosition.CopyTo(bestGlobalPosition, 0);
                        bestGlobalError = newError;
                    }
                    if (currentParticle.Error < AcceptableError)
                    {
                        acceptableErrorReached = true;
                        break;
                    }

                    // particle died so replace it with another one with random starting position
                    double death = rnd.NextDouble();
                    if (death < probabilityOfDeath)
                    {
                        for (int i = 0; i < currentParticle.Coords.Length; i++)
                        {
                            currentParticle.Coords[i] = (problem.MaxX - problem.MinX) * rnd.NextDouble() + problem.MinX;
                        }
                        currentParticle.Error = problem.ErrorFunction(currentParticle.Coords);
                        currentParticle.Coords.CopyTo(currentParticle.BestPosition, 0);
                        currentParticle.BestError = currentParticle.Error;

                        if (currentParticle.Error < bestGlobalError) // randomly got a new global best
                        {
                            bestGlobalError = currentParticle.Error;
                            currentParticle.Coords.CopyTo(bestGlobalPosition, 0);
                        }
                        if (currentParticle.Error < AcceptableError)
                        {
                            acceptableErrorReached = true;
                            break;
                        }
                    }
                }
                currentIteration++;
            }

            // reached maxIterations or acceptableError
            Console.WriteLine("Finished");
            for (int i = 0; i < swarm.Length; i++)
            {
                Console.WriteLine("Particle: " + i);
                Console.WriteLine(swarm[i].ToString());     // print the particles
            }

            double[] finalResult = new double[problem.Dimension];
            bestGlobalPosition.CopyTo(finalResult, 0);
            return(finalResult);                             // return the best global result
        }
        public double[] Solve(IProblem problem)
        {
            Random rnd = new Random();

            Agent[]  population         = new Agent[PopulationSize];
            double[] bestGlobalPosition = new double[problem.Dimension];

            Array.Sort(population);
            Group[] groups = new Group[GroupCount];
            for (int i = 0; i < GroupCount; i++)
            {
                double[] randomPosition = new double[problem.Dimension];
                for (int j = 0; j < randomPosition.Length; j++)
                {
                    randomPosition[j] = (problem.MaxX - problem.MinX) * rnd.NextDouble() + problem.MinX;
                }

                double error = problem.ErrorFunction(randomPosition);

                groups[i] = new Group(new Agent(randomPosition, error), PopulationSize / GroupCount);
            }

            int currentIteration = 0;

            while (currentIteration < MaxIterations)
            {
                for (int i = 0; i < GroupCount; i++)
                {
                    double minDistance = double.MaxValue;

                    double minError  = double.MaxValue;
                    double minError2 = double.MaxValue;

                    double[] minCoords  = new double[problem.Dimension];
                    double[] minCoords2 = new double[problem.Dimension];

                    for (int j = 0; j < GroupCount; j++)
                    {
                        if (i != j)
                        {
                            double distance = groups[i].Head.distanceTo(groups[j].Head);
                            if (minDistance > distance)
                            {
                                minDistance = distance;
                            }
                        }
                    }

                    for (int j = 1; j < groups[i].GroupSize; j++)
                    {
                        double[] randomPosition = new double[problem.Dimension];
                        for (int k = 0; k < randomPosition.Length; k++)
                        {
                            randomPosition[k] = 2 * minDistance * rnd.NextDouble() - minDistance + groups[i].Head.Coords[k];
                        }

                        double error = problem.ErrorFunction(randomPosition);

                        if (error < minError)
                        {
                            minError2 = minError;
                            minCoords.CopyTo(minCoords2, 0);

                            minError = error;
                            randomPosition.CopyTo(minCoords, 0);
                        }
                        else if (error < minError2)
                        {
                            minError2 = error;
                            randomPosition.CopyTo(minCoords2, 0);
                        }
                    }

                    if (minError < groups[i].Head.Error)
                    {
                        if (minError2 < groups[i].Head.Error)
                        {
                            minCoords2.CopyTo(groups[i].Tail.Coords, 0);
                            groups[i].Tail.Error = minError2;
                        }
                        else
                        {
                            groups[i].Head.Coords.CopyTo(groups[i].Tail.Coords, 0);
                            groups[i].Tail.Error = groups[i].Head.Error;
                        }

                        minCoords.CopyTo(groups[i].Head.Coords, 0);
                        groups[i].Head.Error = minError;
                    }
                    else
                    {
                        minCoords.CopyTo(groups[i].Tail.Coords, 0);
                        groups[i].Tail.Error = minError;
                    }
                }

                Array.Sort(groups);
                groups[0].Head.Coords.CopyTo(bestGlobalPosition, 0);
                if (groups[0].Head.Error < AcceptableError)
                {
                    break;
                }

                int removedAgents = groups[GroupCount - 1].GroupSize * 4 / 10;
                groups[GroupCount - 1].GroupSize -= removedAgents;
                if (groups[GroupCount - 1].GroupSize < 2)
                {
                    groups[0].Tail.Coords.CopyTo(groups[GroupCount - 1].Head.Coords, 0);
                    groups[GroupCount - 1].Head.Error = groups[0].Tail.Error;

                    groups[0].GroupSize = groups[0].GroupSize / 2 + groups[0].GroupSize % 2;
                    groups[GroupCount - 1].GroupSize = groups[0].GroupSize /= 2;
                }
                else
                {
                    groups[0].GroupSize += removedAgents;
                }
                currentIteration++;
            }

            return(bestGlobalPosition);
        }