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