/// <summary> /// PSO solver for the rumor problem. /// </summary> /// <param name="relations">Set of initial relations</param> /// <param name="memberNr">Total number of members in said relations</param> /// <param name="populationSize">Size of general population</param> /// <param name="time">Time that the particles are going to search </param> /// <returns></returns> public static List <int[]> ParticleSwarmOptimization(List <int[]> relations, int memberNr, int populationSize = 100, int time = 100) { _relations = relations.ToList(); //check if relations are valid try { SolutionValidator.ValidateSolution(relations, memberNr); } catch (Exception e) { throw e; } int inertia = 2; int cognitiveFactor = 2; int socialFactor = 1; Random random = new Random(); List <Particle> population = new List <Particle>(populationSize); List <Particle> personalBest = new List <Particle>(populationSize); //create the particle population while (!population.Count.Equals(populationSize)) { Particle particle = new Particle(relations.Count); population.Add(particle); personalBest.Add(particle); } //simulate the time lapse for (int i = 0; i < time; i++) { //find the best-looking particle Particle best = GetBestInPopulation(population); for (int j = 0; j < populationSize; j++) { //update the speed of each particle population[j].Speed = inertia * population[j].Speed + cognitiveFactor * random.Next() * HelperFunctions.HammingDistance(personalBest[j].Genes, population[j].Genes) + socialFactor * random.Next() * HelperFunctions.HammingDistance(best.Genes, population[j].Genes); //simulate the movement of a particle population[j] = EvolutiveAlgorithms <Particle> .MutateParticle(population[j]); } } //after the time-lapse, collect all the valid particles List <Particle> validParticles = new List <Particle>(populationSize); foreach (Particle particle in population) { int containingMembers = GetNrOfContainingMembers(particle); //relation set of the particle List <int[]> particleRelations = new List <int[]>(); for (int i = 0; i < particle.Genes.Count; i++) { if (particle.Genes[i].Equals(1)) { particleRelations.Add(_relations[i]); } } try { SolutionValidator.ValidateSolution(particleRelations, memberNr); if (containingMembers.Equals(memberNr)) { validParticles.Add(particle); } } catch (Exception) { //Deliberate suppression of errors. Checking for valid particles } } Particle bestParticle = null; foreach (Particle validParticle in validParticles) { if (GetBestChromosome(validParticle, bestParticle)) { bestParticle = validParticle; } } if (bestParticle == null) { return(null); } List <int[]> bestRelations = new List <int[]>(); for (int i = 0; i < bestParticle.Genes.Count; i++) { if (bestParticle.Genes[i].Equals(1)) { bestRelations.Add(relations[i]); } } return(bestRelations); }
/// <summary> /// Gets the minimal amount of relations needed to spread a rumor between the members /// </summary> /// <param name="relations">Relations between the members. If members are not all conected, throws an exception</param> /// <param name="memberNr">Number of members</param> /// <param name="populationSize">Size of population of EA. Default 100</param> /// <param name="generationAmount">Number of generations to run the algorithm. Default 100</param> /// <returns>A smaller list of relations needed to spread a rumor</returns> public static List <int[]> EvolutiveSearch(List <int[]> relations, int memberNr, int populationSize = 100, int generationAmount = 100) { _relations = relations; //check if relations are valid try { SolutionValidator.ValidateSolution(relations, memberNr); } catch (Exception e) { throw e; } List <Chromosome> population = new List <Chromosome>(); //populate with members while (population.Count < populationSize) { Chromosome chromosome = new Chromosome(relations.Count); population.Add(chromosome); } Random random = new Random(); const double splicingProbability = 0.8; const double mutationProbability = 0.2; //simulate generational evolution for (int i = 0; i < generationAmount; i++) { //select the parent solutions Chromosome parentA = EvolutiveAlgorithms <Chromosome> .TournamentSelection( population, GetBestChromosome, 6); Chromosome parentB = EvolutiveAlgorithms <Chromosome> .TournamentSelection( population, GetBestChromosome, 6); //decide randomly on the cut point int cutPoint = random.Next(memberNr); //get the offsprings of the parents List <Chromosome> offsprings = EvolutiveAlgorithms <Chromosome> .SpliceChromosomes( parentA, parentB, cutPoint, splicingProbability); //if there has been no splicing, skips this if if (offsprings != null) { //mutate the offsprings for (int j = 0; j < offsprings.Count; j++) { offsprings[j] = EvolutiveAlgorithms <Chromosome> .MutateChromosome(offsprings[j], mutationProbability); } //find the index of the worst member of the population int worstIndex = 0; for (int j = 0; j < population.Count; j++) { if (GetBestChromosome(population[worstIndex], population[j])) { worstIndex = j; } } //select the best descendant Chromosome bestOffspring = offsprings[0]; if (GetBestChromosome(offsprings[1], offsprings[0])) { bestOffspring = offsprings[1]; } //if the best descendant is better than the worst member of the population //replace him if (GetBestChromosome(bestOffspring, population[worstIndex])) { population[worstIndex] = bestOffspring; } } } //after all the generations passed, filter them based on the ones that are a valid solution List <Chromosome> validChromosomes = new List <Chromosome>(populationSize); foreach (Chromosome chromosome in population) { int containingMembers = GetNrOfContainingMembers(chromosome); List <int[]> chromosomeRelations = new List <int[]>(); for (int i = 0; i < chromosome.Genes.Count; i++) { if (chromosome.Genes[i].Equals(1)) { chromosomeRelations.Add(_relations[i]); } } try { SolutionValidator.ValidateSolution(chromosomeRelations, memberNr); if (containingMembers.Equals(memberNr)) { validChromosomes.Add(chromosome); } } catch (Exception) { //Deliberate suppression of errors. Checking for valid chromosomes } } Chromosome best = null; //get the best solution out of all existing foreach (Chromosome validChromosome in validChromosomes) { if (GetBestChromosome(validChromosome, best)) { best = validChromosome; } } if (best == null) { return(null); } List <int[]> bestRelations = new List <int[]>(); for (int i = 0; i < best.Genes.Count; i++) { if (best.Genes[i].Equals(1)) { bestRelations.Add(relations[i]); } } return(bestRelations); }