public void Mutate() { var cycles = Math.Round(NEMath.RandomBetween(1, this.config.MaxMutationCycles, this.config.MutationCycleBias), 0); while (cycles > 0) { var chance = NEMath.Random(); if (chance < this.config.AxionMutationRate) { var layer = this.Axions[NEMath.RNG.Next(0, this.Axions.Length)]; var axion = layer[NEMath.RNG.Next(0, layer.Length)]; if (chance < this.config.AxionReplacementRate) { axion.Weight = NEMath.Clamp(NEMath.RandomBetween(-1, 1), -1.0, 1.0); } else { axion.Weight = NEMath.Clamp(axion.Weight + NEMath.RandomBetween(-0.1, 0.1), -1.0, 1.0); } } cycles -= 1; } }
public Network Crossover(Network partner, bool ignoreStrength = false) { var maxCreationGeneration = (this.CreationGeneration > partner.CreationGeneration) ? this.CreationGeneration : partner.CreationGeneration; var offspring = new Network(this.config.Clone(), NetworkOrigins.CROSSOVER, maxCreationGeneration + 1) { AncestralGeneration = this.AncestralGeneration }; for (var i = 0; i < this.Axions.Length; i++) { for (var j = 0; j < this.Axions[i].Length; j++) { var selfAxion = this.Axions[i][j]; var partnerAxion = partner.Axions[i][j]; var offspringAxion = offspring.Axions[i][j]; var strongestWeight = (this.Strength > partner.Strength) ? selfAxion.Weight : partnerAxion.Weight; var weakestWeight = (this.Strength < partner.Strength) ? selfAxion.Weight : partnerAxion.Weight; if (ignoreStrength) { strongestWeight = selfAxion.Weight; weakestWeight = partnerAxion.Weight; } var chance = (NEMath.Random() * this.config.CrossoverBias + 0.50); chance = (ignoreStrength) ? 0.5 : chance; offspringAxion.Weight = (NEMath.Random() < chance) ? strongestWeight : weakestWeight; } } return(offspring); }
public void RandomiseAxions() { for (var i = 0; i < this.Axions.Length; i++) { for (var j = 0; j < this.Axions[i].Length; j++) { var axion = this.Axions[i][j]; // Randomise, but bias towards zero. var randomWeight = NEMath.RandomBetween(0, 1, 0.25); if (NEMath.Random() < 0.5) { randomWeight *= -1.0; } axion.Weight = randomWeight; } } }
public void Evolve(ref List <Network> travellerCandidates) { // Sort networks by strength. this.Networks = this.Networks.OrderByDescending(o => o.Strength).ToList(); // Cull weakest half of networks. if (this.Networks.Count > 1) { var half = (int)Math.Round((double)this.Networks.Count / 2, 0); this.Networks = this.Networks.Take(half).ToList(); } // Fill opened space with new networks. var newNetworks = new List <Network>(); if (this.Networks.Count < this.clusterConfig.MaxNetworks) { var clones = this.Networks.Where(o => o.Origin == NetworkOrigins.CLONE).Count(); var travellers = this.Networks.Where(o => o.Origin == NetworkOrigins.TRAVELLER).Count(); var others = this.Networks.Where(o => o.Origin != NetworkOrigins.CLONE && o.Origin != NetworkOrigins.TRAVELLER).Count(); var maxClones = Math.Round(this.clusterConfig.MaxNetworks * this.clusterConfig.CloneRatio, 0); var maxTravellers = Math.Round(this.clusterConfig.MaxNetworks * this.clusterConfig.TravellerRatio, 0); var maxOthers = this.clusterConfig.MaxNetworks - maxClones - maxTravellers; var deltaClones = NEMath.Clamp(maxClones - clones, 0, maxClones); var deltaTravellers = NEMath.Clamp(maxTravellers - travellers, 0, maxClones); var deltaOthers = NEMath.Clamp(maxOthers - others, 0, maxOthers); while (deltaClones > 0) { var biasedIndex = (int)Math.Round(NEMath.RandomBetween(0, this.Networks.Count - 1, 5.0), 0); newNetworks.Add(this.Networks[biasedIndex].Clone()); deltaClones -= 1; } while (deltaTravellers > 0 && travellerCandidates.Count > 0) { newNetworks.Add(travellerCandidates[0]); travellerCandidates.RemoveAt(0); } while (deltaOthers > 0 && this.Networks.Count > 1) { var biasedIndexA = (int)Math.Round(NEMath.RandomBetween(0, this.Networks.Count - 1, 2.5), 0); var biasedIndexB = (int)Math.Round(NEMath.RandomBetween(0, this.Networks.Count - 1, 2.5), 0); if (biasedIndexA == biasedIndexB) { continue; } var parentA = this.Networks[biasedIndexA]; var parentB = this.Networks[biasedIndexB]; newNetworks.Add(parentA.Crossover(parentB)); deltaOthers -= 1; } } // Mutate existing networks (except strongest) for (var i = 1; i < this.Networks.Count; i++) { if (NEMath.Random() < this.clusterConfig.HeavyMutationRate) { this.Networks[i].HeavilyMutuate(0.25); } else { this.Networks[i].Mutate(); } } // Add new networks to cluster. this.Networks.AddRange(newNetworks); }
public static double RandomBetween(double min, double max, double biasingPower = 1) { return(NEMath.Random(biasingPower) * (max - min) + min); }