Beispiel #1
0
        private byte Swap(Gene gene, ushort geneIndex)
        {
            ushort otherIndex = geneIndex;

            do
            {
                otherIndex = CROSSOVER_GEN.GetNext();
            } while (otherIndex == geneIndex);

            Gene otherGene = Genes[otherIndex];

            // this function handles the swap for both genes
            return(gene.FullSwap(otherGene));
        }
Beispiel #2
0
        // gene pool is a list of every possible event block, most of which will be inactive
        public static int CreatePool(string infoFilesFolder)
        {
            Path = infoFilesFolder;
            AddParameterType("Day", false, 1, 2, 3, 4, 5);
            AddParameterType("Time", false, 0, 1, 2, 3, 4, 5, 6);

            string path          = infoFilesFolder.TrimEnd('\\') + "\\";
            var    activitiesCSV = Utils.LoadCSV <ActivityCSV>(path + "Activities.csv");
            var    activities    = activitiesCSV.Select(a => a.ToInfo()).ToList();
            var    exclusives    = activities.Select((a, i) => new { Index = i, Activity = a }).Where(a => a.Activity.Flags.HasFlag(ActivityFlags.Manual));
            var    dorms         = File.ReadAllLines(
                path + "ExclusiveActivities.txt"
                ).Select(
                l =>
            {
                var split = l.Split(
                    new string[] { " - ", ", " },
                    StringSplitOptions.None
                    );
                return(new DormInfo(
                           split[0],
                           split.Skip(1).Select(
                               a => Convert.ToInt32(a)
                               ).ToArray()
                           ));
            }
                ).ToArray();
            var manuallyScheduled = Utils.LoadCSV <ManuallyScheduledCSV>(path + "Manually Scheduled.csv").OrderBy(a => a.Day).ThenBy(a => a.Start).ThenBy(a => a.Dorm).ToList();
            var blocks            = Utils.LoadCSV <BlockCSV>(path + "Days.csv");

            AddParameterType("Activity", false, Enumerable.Range(0, activities.Count).Select(a => (byte)a).ToArray());
            var dormBytes = Enumerable.Range(0, dorms.Count()).Select(d => (byte)d).Append <byte>(255).ToArray();

            AddParameterType("Dorm", true, dormBytes);
            AddParameterType("OtherDorm", true, dormBytes.Skip(1).ToArray());
            dormBytes = null;

            var immutableList = new List <Gene>();

            int    blockIndex = 0;
            byte   time       = 0;
            ushort geneID     = ushort.MaxValue;

            foreach (var manual in manuallyScheduled)
            {
                while (blocks[blockIndex].Day < manual.Day)
                {
                    ++blockIndex;
                    time = 0;
                }
                while (blocks[blockIndex].Hour < manual.Start.Hours || blocks[blockIndex].Minute < manual.Start.Minutes)
                {
                    ++blockIndex;
                    ++time;
                }

                int  blockIndexTemp = blockIndex;
                byte timeTemp       = time;
                do
                {
                    immutableList.Add(
                        new Gene(
                            geneID,
                            new byte[]
                    {
                        (byte)manual.Day,
                        time,
                        (byte)exclusives.First(a => a.Activity.Abbreviation == manual.Activity).Index,
                        (byte)Array.FindIndex(dorms, d => d.Abbreviation == manual.Dorm),
                        255
                    },
                            true
                            )
                        );
                    --geneID;
                    ++blockIndexTemp;
                    ++timeTemp;
                } while (
                    blockIndexTemp < blocks.Length &&
                    blocks[blockIndexTemp].Day == manual.Day &&
                    blocks[blockIndexTemp].Hour < manual.End.Hours &&
                    blocks[blockIndexTemp].Minute < manual.End.Minutes
                    );
            }

            ImmutableGenes = immutableList.ToArray();
            immutableList  = null;

            //List<Gene> genePool = new List<Gene>();
            //List<Tuple<byte, byte, byte>> genePool = new List<Tuple<byte, byte, byte>>();
            List <SimpleImmutable> genePool = new List <SimpleImmutable>();

            geneID = 0;
            var  activitiesByDuration = activities.FindAll(a => !a.Flags.HasFlag(ActivityFlags.Manual) && !a.Flags.HasFlag(ActivityFlags.Concurrent)).GroupBy(a => a.Duration);
            byte concurrentActivity   = (byte)activities.First(a => a.Flags.HasFlag(ActivityFlags.Concurrent)).ID;

            SetupConsts(dorms, activities, path);
            List <byte> times     = new List <byte>();
            List <byte> tailTimes = new List <byte>();
            //Constants.SURVIVAL_DAYINFO = new DaySurvivalInfo[((byte)blocks.Last().Day) + 1];

            int  pointer       = 0;
            byte currentDay    = 0;
            byte dayGenesCount = 0;

            byte[] timesGenesCounts = new byte[7];
            byte   currentTime      = 0; // time in the day

            while (pointer < blocks.Length)
            {
                List <BlockCSV> currentBlocks = new List <BlockCSV>();
                BlockCSV        nextBlock     = blocks[pointer];
                BlockCSV        lastBlock     = new BlockCSV();

                byte total     = 0;  // total number of blocks in the set
                byte available = 0;  // number of blocks in the set available to start activities
                byte excess    = 0;

                // time at the start of this blockset
                byte timeTemp = currentTime;

                do
                {
                    currentBlocks.Add(nextBlock);
                    lastBlock = nextBlock;
                    ++total;
                    if (lastBlock.Excess)
                    {
                        ++excess;
                    }
                    else
                    {
                        ++available;
                    }
                    ++pointer;
                    ++currentTime;
                    if (pointer != blocks.Length)
                    {
                        nextBlock = blocks[pointer];
                    }
                } while (
                    pointer < blocks.Length &&
                    nextBlock.Day == lastBlock.Day &&
                    nextBlock.Hour - lastBlock.Hour <= 1
                    );
                tailTimes.Add((byte)(timeTemp + available - 1));

                foreach (var duration in activitiesByDuration)
                {
                    if (duration.Key > currentBlocks.Count)
                    {
                        continue;
                    }
                    for (byte actualTime = timeTemp; actualTime < available + timeTemp; actualTime = (byte)(actualTime + duration.Key))
                    {
                        //byte actualTime = (byte)(currentTime + timeOffset);
                        foreach (var activity in duration)
                        {
                            /*genePool.Add(
                             *  new Gene(
                             *      geneID,
                             *      new byte[]
                             *      {
                             *          currentDay,
                             *          actualTime,
                             *          (byte)activity.ID,
                             *          255,
                             *          255
                             *      }
                             *  )
                             * );*/
                            genePool.Add(new SimpleImmutable(currentDay, actualTime, (byte)activity.ID));
                            //++geneID;
                            ++dayGenesCount;
                            ++timesGenesCounts[actualTime];
                        }
                    }
                }

                for (byte actualTime = timeTemp; actualTime < available; ++actualTime)
                {
                    /*genePool.Add(
                     *  new Gene(
                     *      geneID,
                     *      new byte[]
                     *      {
                     *          currentDay,
                     *          actualTime,
                     *          concurrentActivity,
                     *          255,
                     *          255
                     *      }
                     *  )
                     * );
                     ++geneID;*/
                    genePool.Add(new SimpleImmutable(currentDay, actualTime, concurrentActivity));
                    ++dayGenesCount;
                    ++timesGenesCounts[actualTime];
                }

                if (nextBlock.Day != lastBlock.Day)
                {
                    /*Constants.SURVIVAL_DAYINFO[currentDay] = new DaySurvivalInfo(
                     *  timesGenesCounts,
                     *  tailTimes,
                     *  dayGenesCount
                     * );*/
                    timesGenesCounts = new byte[7];
                    dayGenesCount    = 0;
                    ++currentDay;
                    currentTime = 0;
                }
            }

            int numGenes = genePool.Count;

            NUM_GENES = (byte)numGenes;
            Chromosome.CROSSOVER_GEN = new ByteGenerator((byte)numGenes);
            Pool       = new Chromosome[POOL_SIZE];
            SamplePool = new Chromosome[SAMPLE_POOL_SIZE];
            Func <GeneParameter[]> getGeneParams = () => GeneParams;

            ImmutableValues = genePool.ToArray();

            /*
             * for (int i = 0; i < numGenes; ++i)
             * {
             *  var gene = genePool[i];
             *  ImmutableValues[i, 0] = gene.Item1;
             *  ImmutableValues[i, 1] = gene.Item2;
             *  ImmutableValues[i, 2] = gene.Item3;
             * }*/
            genePool = null;

            for (int c = 0; c < POOL_SIZE; ++c)
            {
                Gene[] chromosome = new Gene[numGenes];
                for (int g = 0; g < numGenes; ++g)
                {
                    //chromosome[g] = genePool[g].Randomize(2);
                }
                Pool[c] = new Chromosome(chromosome, getGeneParams);
            }

            PoolMinFitness = 0;
            return(numGenes);
        }
Beispiel #3
0
        public Chromosome[] CrossoverWith(Chromosome other, int maxOffspring)
        {
            throw new NotImplementedException();

            var geneParams   = GetGeneParameters();
            int numOffspring = (int)(maxOffspring * Stats.Fertility * other.Stats.Fertility) + 1;

            if (numOffspring % 2 == 1)
            {
                ++numOffspring;
            }
            int numGenes = Genes.Length;

            Chromosome[] offspring = new Chromosome[numOffspring];
            for (int i = 0; i < numOffspring; i += 2)
            {
                int twins      = 0;
                int twinsIndex = i;
                while (GEN.NextDouble() < TWIN_RATE && ++twinsIndex < numOffspring)
                {
                    ++twins;
                }

                if (twins > 0)
                {
                    byte[][] child = new byte[geneParams.Length][];

                    // partial crossover
                    for (byte paramIndex = 0; paramIndex < GenePool.NUM_IMMUTABLE; ++paramIndex)
                    {
                        var point1 = GEN.Next(Genes.Length);
                        var point2 = GEN.Next(Genes.Length);
                        if (point2 > point1)
                        {
                            var temp = point2;
                            point2 = point1;
                            point1 = temp;
                        }

                        byte[] childGenes = new byte[Genes.Length];
                        SortedDictionary <byte, byte> swapper = new SortedDictionary <byte, byte>();

                        for (int p = point1; p <= point2; ++p)
                        {
                            byte parent1 = Genes[p][paramIndex];
                            byte parent2 = other.Genes[p][paramIndex];
                            if (parent1 == parent2)                           // shared compatibility/incompatibility
                            {
                                if (!Stats.Survives || !other.Stats.Survives) // shared incompatibility
                                {
                                    //child[p] = GenePool.GetGeneParamRandomValue(paramIndex);
                                }
                                else
                                {
                                    //child1Genes[p] = parent1;
                                    //child2Genes[p] = parent2;
                                }
                            }
                            else
                            {
                                swapper.Add(parent1, parent2);
                                swapper.Add(parent2, parent1);
                            }
                        }

                        for (int p = 0; p < Genes.Length; ++p)
                        {
                            // gets this parameter from each gene

                            byte value1 = Genes[p][paramIndex];
                            childGenes[p] = swapper.TryGetValue(value1, out byte value) ? value : value1;
                        }

                        child[paramIndex] = childGenes;
                    }

                    // simple crossover
                    for (byte paramIndex = GenePool.NUM_IMMUTABLE; paramIndex < GenePool.NUM_PARAMS; ++paramIndex)
                    {
                        var point1 = GEN.Next(Genes.Length);
                        var point2 = GEN.Next(Genes.Length);
                        if (point2 > point1)
                        {
                            var temp = point2;
                            point2 = point1;
                            point1 = temp;
                        }

                        byte[] childGenes = new byte[Genes.Length];
                        for (int p = point1; p < point2; ++p)
                        {
                            childGenes[p] = Genes[p][paramIndex];
                        }

                        for (int p = point2; p < Genes.Length; ++p)
                        {
                            childGenes[p] = other.Genes[p][paramIndex];
                        }
                        for (int p = 0; p < point1; ++p)
                        {
                            childGenes[p] = other.Genes[p][paramIndex];
                        }

                        child[paramIndex] = childGenes;
                    }

                    Gene[] genes = new Gene[numGenes];
                    for (ushort g = 0; g < numGenes; ++g)
                    {
                        byte[] gene = new byte[geneParams.Length];
                        for (int p = 0; p < geneParams.Length; ++p)
                        {
                            gene[p] = child[p][g];
                        }
                        genes[g] = new Gene(g, gene);
                    }


                    if (twins % 2 == 0)
                    {
                        ++twinsIndex;
                    }
                    offspring[i] = new Chromosome(genes, GetGeneParameters);
                    for (int k = i + 1; k <= twinsIndex; ++k)
                    {
                        offspring[k] = new Chromosome(genes, GetGeneParameters);
                    }

                    i = twinsIndex - 1;
                }
                else
                {
                    byte[][] child1 = new byte[geneParams.Length][];
                    byte[][] child2 = new byte[geneParams.Length][];

                    // partial crossover
                    for (byte paramIndex = 0; paramIndex < GenePool.NUM_IMMUTABLE; ++paramIndex)
                    {
                        //var geneParam = geneParams[index];
                        (child1[paramIndex], child2[paramIndex]) = PartialCrossover(other, paramIndex);
                    }

                    // simple crossover
                    for (byte paramIndex = GenePool.NUM_IMMUTABLE; paramIndex < GenePool.NUM_PARAMS; ++paramIndex)
                    {
                        (child1[paramIndex], child2[paramIndex]) = SimpleCrossover(other, paramIndex);
                    }

                    Gene[] genes1 = new Gene[numGenes];
                    Gene[] genes2 = new Gene[numGenes];
                    for (ushort g = 0; g < numGenes; ++g)
                    {
                        byte[] gene1 = new byte[geneParams.Length];
                        byte[] gene2 = new byte[geneParams.Length];
                        for (int p = 0; p < geneParams.Length; ++p)
                        {
                            gene1[p] = child1[p][g];
                            gene2[p] = child2[p][g];
                        }
                        genes1[g] = new Gene(g, gene1);
                        genes2[g] = new Gene(g, gene2);
                    }

                    offspring[i]     = new Chromosome(genes1, GetGeneParameters);
                    offspring[i + 1] = new Chromosome(genes2, GetGeneParameters);
                }
            }

            return(offspring);
        }