Пример #1
0
        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;
            }
        }
Пример #2
0
        /// <summary>
        /// <para>Brings together all networks, and forces the creation of a new diversified pool of networks.</para>
        /// <para>Existing clusters will be cleared, and all existing networks (except the strongest) purged.</para>
        ///
        /// <para>The new pool of networks will initially be archived, and will need to be assessed and then clustered.</para>
        ///
        /// <seealso cref="Cluster"/>
        /// </summary>
        public void Merge()
        {
            var existingNetworks = this.GetAllNetworks().OrderByDescending(o => o.Strength).ToList();

            this.Clusters.Clear();
            this.NetworkArchive.Clear();

            if (existingNetworks.Count < 1)
            {
                return;
            }

            var maxNetworks = this.ClusterConfig.MaxNetworks * this.SuperclusterConfig.MaxClusters;
            var maxClones   = Math.Round(maxNetworks * this.ClusterConfig.CloneRatio, 0);

            // Prime population with clones of the strongest mutation.
            // One perfect clone, two imperfect clones, and two heavily mutated clones.
            this.NetworkArchive.Add(existingNetworks[0].Clone(true));
            this.NetworkArchive.Add(existingNetworks[0].Clone());
            this.NetworkArchive.Add(existingNetworks[0].Clone());
            this.NetworkArchive.Add(existingNetworks[0].Clone());
            this.NetworkArchive.Add(existingNetworks[0].Clone());

            this.NetworkArchive[3].HeavilyMutuate(0.25);
            this.NetworkArchive[4].HeavilyMutuate(0.50);

            // Fill the clone quota, strongly biased towards stronger networks.
            while (this.NetworkArchive.Count < maxClones)
            {
                var biasedIndex = (int)Math.Round(NEMath.RandomBetween(0, existingNetworks.Count - 1, 5.0), 0);

                this.NetworkArchive.Add(existingNetworks[biasedIndex].Clone());
            }

            // Fill the remaining quota via crossover, moderately biased towards strong networks.
            while (this.NetworkArchive.Count < maxNetworks)
            {
                var biasedIndexA = (int)Math.Round(NEMath.RandomBetween(0, existingNetworks.Count - 1, 2.5), 0);
                var biasedIndexB = (int)Math.Round(NEMath.RandomBetween(0, existingNetworks.Count - 1, 2.5), 0);

                if (biasedIndexA == biasedIndexB)
                {
                    continue;
                }

                var parentA = existingNetworks[biasedIndexA];
                var parentB = existingNetworks[biasedIndexB];

                this.NetworkArchive.Add(parentA.Crossover(parentB));
            }
        }
Пример #3
0
        public void HeavilyMutuate(double perAxionChance)
        {
            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];

                    if (NEMath.RNG.NextDouble() < perAxionChance)
                    {
                        axion.Weight = NEMath.Clamp(axion.Weight + NEMath.RandomBetween(-0.5, 0.5), -1.0, 1.0);
                    }
                    ;
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Triggers an evolution cycle for all clustered networks. Does not effect archived networks.
        /// </summary>
        public void Evolve()
        {
            var maxTravellers = Math.Round(this.ClusterConfig.MaxNetworks * this.ClusterConfig.TravellerRatio, 0);

            foreach (var cluster in this.Clusters)
            {
                var travellerCandidates = new List <Network>();

                while (travellerCandidates.Count < maxTravellers && this.NetworkArchive.Count > 0)
                {
                    var biasedIndex = (int)Math.Round(NEMath.RandomBetween(0, this.NetworkArchive.Count - 1, 0.1), 0);

                    travellerCandidates.Add(this.NetworkArchive[biasedIndex]);
                    this.NetworkArchive.RemoveAt(biasedIndex);
                }

                cluster.Evolve(ref travellerCandidates);

                this.NetworkArchive.AddRange(travellerCandidates);
            }
        }
Пример #5
0
        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;
                }
            }
        }
Пример #6
0
        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);
        }