예제 #1
0
        public static Hunter[] Crossover(Hunter a, Hunter b)
        {
            Hunter[] ret = new Hunter[2];
            string   bDebugStr = b.HumanReadableHunter, aDebugStr = a.HumanReadableHunter;

            ret[0] = new Hunter().StripChromosomes();
            ret[1] = new Hunter().StripChromosomes();

            Hunter target = ret[0], notTarget = ret[1], mostChromosomes;

            Chromosome[] temp = new Chromosome[2];//If a has 7 Chromosomes, and b has 3,
            //we want to end as soon as either fails
            //So if a and b both have count 3, a is true, but b is false, so the comparison fails
            List <int> aCrossed = new List <int>(a.myChromosomes.Count), bCrossed = new List <int>(b.myChromosomes.Count);
            List <int> mostCrossed;
            int        max = Math.Min(a.myChromosomes.Count, b.myChromosomes.Count), point1 = OptoGlobals.RNG.Next(0, max), point2 = OptoGlobals.RNG.Next(point1, max);
            Hunter     maxHunter = a.myChromosomes.Count == max?b:a;

            #region CrossoverModeBlock
            switch (OptoGlobals.CrossoverMode)
            {
            case OptoGlobals.CrossoverModes.Uniform:
                for (int i = 0; i < max; ++i)
                {
                    //Trying a form of uniform crossover, 2 point
                    //just swapping chromosomes, not crossing over at that level
                    temp = Chromosome.CrossOver(a[i].deepCopy(), b[i].deepCopy());

                    target.AddChromosome(temp[0]);
                    notTarget.AddChromosome(temp[1]);
                    aCrossed.Add(i);
                    bCrossed.Add(i);
                    if (OptoGlobals.RNG.NextDouble() <= OptoGlobals.CrossoverChance)
                    {
                        switchTargets(ret[0], ret[1], ref target, ref notTarget);
                    }
                }
                for (int i = max; i < maxHunter.myChromosomes.Count; ++i)
                {
                    target.AddChromosome(maxHunter[i]);
                    if (OptoGlobals.RNG.NextDouble() <= OptoGlobals.CrossoverChance)
                    {
                        switchTargets(ret[0], ret[1], ref target, ref notTarget);
                    }
                }
                break;

            case OptoGlobals.CrossoverModes.TwoPointHunter:
                for (int i = 0; i < max; ++i)
                {
                    //Trying a form of uniform crossover, 2 point
                    //just swapping chromosomes, not crossing over at that level
                    //temp = Chromosome.CrossOver(a[i], b[i]);
                    target.AddChromosome(a[i]);
                    notTarget.AddChromosome(b[i]);
                    aCrossed.Add(i);
                    bCrossed.Add(i);
                    if (i == point1 || i == point2)
                    {
                        switchTargets(ret[0], ret[1], ref target, ref notTarget);
                    }
                }
                break;

            case OptoGlobals.CrossoverModes.SinglePointHunter:
                for (int i = 0; i < max; ++i)
                {
                    //Trying a form of uniform crossover, 2 point
                    //just swapping chromosomes, not crossing over at that level
                    //temp = Chromosome.CrossOver(a[i], b[i]);
                    target.AddChromosome(a[i]);
                    notTarget.AddChromosome(b[i]);
                    aCrossed.Add(i);
                    bCrossed.Add(i);
                    if (i == point1)
                    {
                        switchTargets(ret[0], ret[1], ref target, ref notTarget);
                    }
                }
                break;

            case OptoGlobals.CrossoverModes.TwoPointChromosome:
                for (int i = 0; i < max; ++i)
                {
                    //Trying a form of uniform crossover, 2 point
                    //just swapping chromosomes, not crossing over at that level
                    temp = Chromosome.CrossOver(a[i], b[i]);
                    target.AddChromosome(temp[0]);
                    notTarget.AddChromosome(temp[1]);
                    aCrossed.Add(i);
                    bCrossed.Add(i);
                    if (i == point1 || i == point2)
                    {
                        switchTargets(ret[0], ret[1], ref target, ref notTarget);
                    }
                }
                break;

            case OptoGlobals.CrossoverModes.SinglePointChromosome:
                for (int i = 0; i < max; ++i)
                {
                    //Trying a form of uniform crossover, 2 point
                    //just swapping chromosomes, not crossing over at that level
                    temp = Chromosome.CrossOver(a[i], b[i]);
                    target.AddChromosome(temp[0]);
                    notTarget.AddChromosome(temp[1]);
                    aCrossed.Add(i);
                    bCrossed.Add(i);
                    if (i == point1)
                    {
                        switchTargets(ret[0], ret[1], ref target, ref notTarget);
                    }
                }
                break;

            case OptoGlobals.CrossoverModes.RandomHunter:

                while (aCrossed.Count != a.myChromosomes.Count && bCrossed.Count != b.myChromosomes.Count)
                {
                    int i = SupportingFunctions.GetUnpickedInt(a.myChromosomes.Count, aCrossed);
                    int j = SupportingFunctions.GetUnpickedInt(b.myChromosomes.Count, bCrossed);
                    if (OptoGlobals.RNG.NextDouble() <= OptoGlobals.CrossoverChance)
                    {
                        switchTargets(ret[0], ret[1], ref target, ref notTarget);
                    }
                    //temp = Chromosome.CrossOver(a[i], b[j]);
                    target.AddChromosome(a[i]);
                    notTarget.AddChromosome(b[j]);
                    aCrossed.Add(i);
                    bCrossed.Add(j);
                }
                break;

            case OptoGlobals.CrossoverModes.RandomChromosome:
                while (aCrossed.Count != a.myChromosomes.Count && bCrossed.Count != b.myChromosomes.Count)
                {
                    int i = SupportingFunctions.GetUnpickedInt(a.myChromosomes.Count, aCrossed);
                    int j = SupportingFunctions.GetUnpickedInt(b.myChromosomes.Count, bCrossed);
                    if (OptoGlobals.RNG.NextDouble() <= OptoGlobals.CrossoverChance)
                    {
                        switchTargets(ret[0], ret[1], ref target, ref notTarget);
                    }
                    temp = Chromosome.CrossOver(a[i], b[j]);
                    target.AddChromosome(temp[0]);
                    notTarget.AddChromosome(temp[1]);
                    aCrossed.Add(i);
                    bCrossed.Add(j);
                }
                break;
            }
            #endregion
            if (aCrossed.Count == a.myChromosomes.Count)
            {
                mostChromosomes = b;
                mostCrossed     = bCrossed;
            }
            else
            {
                mostChromosomes = a;
                mostCrossed     = aCrossed;
            }
            //Randomly distribute the remaining Chromosomes
            while (mostCrossed.Count != mostChromosomes.myChromosomes.Count)
            {
                if (OptoGlobals.RNG.NextDouble() <= OptoGlobals.CrossoverChance)
                {
                    switchTargets(ret[0], ret[1], ref target, ref notTarget);
                }
                int i = SupportingFunctions.GetUnpickedInt(mostChromosomes.myChromosomes.Count, mostCrossed);
                target.AddChromosome(mostChromosomes[i]);
                mostCrossed.Add(i);
            }

            string aOutStr = a.HumanReadableHunter, bOutStr = b.HumanReadableHunter;

            Debug.Assert(aOutStr == aDebugStr && bOutStr == bDebugStr);


            ret[0].updateCellNum();
            ret[1].updateCellNum();
            return(ret);

            /*           Hunter[] ret = new Hunter[2];
             *         ret[0] = new Hunter().StripChromosomes();
             *         ret[1] = new Hunter().StripChromosomes();
             *         Hunter target = ret[0], notTarget = ret[1], mostChromosomes;
             *         Chromosome[] temp = new Chromosome[2];
             *         int min = Math.Min(a.myChromosomes.Count, b.myChromosomes.Count);
             *         for (int i = 0; i < min; ++i)
             *         {
             *             if (OptoGlobals.RNG.NextDouble() <= OptoGlobals.CrossoverChance) Hunter.switchTargets(ret[0], ret[1], ref target, ref notTarget);
             *             temp = Chromosome.CrossOver(a[i], b[i]);
             *             target[i] = temp[0];
             *             notTarget[i] = temp[1];
             *         }
             *
             *         int max = Math.Max(a.myChromosomes.Count, b.myChromosomes.Count);
             *         if (max == a.myChromosomes.Count) mostChromosomes = a;
             *         else mostChromosomes = b;
             *
             *         for (int i = min; i < max; i++)
             *         {
             *             if (OptoGlobals.RNG.NextDouble() <= OptoGlobals.CrossoverChance) switchTargets(ret[0], ret[1], ref target, ref notTarget);
             *             if (mostChromosomes[i] != null)
             *                 target[i] = mostChromosomes[i];
             *         }
             *         ret[0].updateCellNum();
             *         ret[1].updateCellNum();
             *         return ret;
             */
        }
예제 #2
0
 protected Hunter(Chromosome x) : this()
 {
     myChromosomes = new List <Chromosome>();
     myChromosomes.RemoveAt(0);
     this.AddChromosome(x);
 }
예제 #3
0
 public void AddChromosome(Chromosome x)
 {
     x.updateCellNum();
     myChromosomes.Add(x.deepCopy());
 }