-4

Ok so I finished my code n queens genetics in c# but I keep getting these compiler errors even though I changed the code several times

 using System;
using System.Collections.Generic;
using System.Linq;
 using System.Text;
 using System.Threading.Tasks;

 namespace NQueen1
{
     class Program
{
   private const int sSize = 75; // Population size at start.
  private  const int mTest = 1000; // Arbitrary number of test cycles.
  private  const double pMating = 0.7; // Probability of two chromosomes mating. Range: 0.0 < MATING_PROBABILITY < 1.0
private const double rMutation = 0.001; // Mutation Rate. Range: 0.0 < MUTATION_RATE < 1.0
  private const int minS = 10; // Minimum parents allowed for selection.
    private const int MaxS = 50; // Maximum parents allowed for selection. Range: MIN_SELECT < MAX_SELECT < START_SIZE
    private const int offSpring = 20; // New offspring created per generation. Range: 0 < OFFSPRING_PER_GENERATION < MAX_SELECT.
    private const int minRandom = 8; // For randomizing starting chromosomes
    private const int maxShuffles = 20;
   private const int maxPBC = 4; // Maximum Position-Based Crossover points. Range: 0 < PBC_MAX < 8 (> 8 isn't good).

   private  const int maxLength = 10; // chess board width.

  private static  int epoch = 0;
  private  static int childCount = 0;
   private static int nextMutation = 0; // For scheduling mutations.
    private static int mutations = 0;

 private static   List<Chromosome> population = new List<Chromosome>();

  private static  void algorithm()
    {
        int popSize = 0;
        Chromosome thisChromo = null;
        bool done = false;

        initializeChromosomes();
        mutations = 0;
        nextMutation = getRandomNumber(0, (int)Math.Round(1.0 / rMutation));

        while (!done)
        {
            popSize = population.Count;
            for (int i = 0; i < popSize; i++)
            {
                thisChromo = population[i];
                if ((thisChromo.conflicts() == 0) || epoch == mTest)
                {
                    done = true;
                }
            }

            getFitness();


            rouletteSelection();

            mating();

            prepNextEpoch();

            epoch++;
            // This is here simply to show the runtime status.
            Console.WriteLine("Epoch: " + epoch);
        }

        Console.WriteLine("done.");

        if (epoch != rMutation)
        {
            popSize = population.Count;
            for (int i = 0; i < popSize; i++)
            {
                thisChromo = population[i];
                if (thisChromo.conflicts() == 0)
                {
                    printSolution(thisChromo);
                }
            }
        }
        Console.WriteLine("Completed " + epoch + " epochs.");
        Console.WriteLine("Encountered " + mutations + " mutations in " + childCount + " offspring.");
        return;
    }

 private static   void getFitness()
    {
        // Lowest errors = 100%, Highest errors = 0%
        int popSize = population.Count;
        Chromosome thisChromo = null;
        double bestScore = 0;
        double worstScore = 0;

        // The worst score would be the one with the highest energy, best would be lowest.
        worstScore = population[maximum()].conflicts();

        // Convert to a weighted percentage.
        bestScore = worstScore - population[minimum()].conflicts();

        for (int i = 0; i < popSize; i++)
        {
            thisChromo = population[i];
            thisChromo.fitness((worstScore - thisChromo.conflicts()) * 100.0 / bestScore);
        }

        return;
    }

   private static void rouletteSelection()
    {
        int j = 0;
        int popSize = population.Count;
        double genT = 0.0;
        double selT = 0.0;
        int maximumToSelect = getRandomNumber(minS, MaxS);
        double rouletteSpin = 0.0;
        Chromosome thisChromo = null;
        Chromosome thatChromo = null;
        bool done = false;

        for (int i = 0; i < popSize; i++)
        {
            thisChromo = population[i];
            genT += thisChromo.fitness();
        }

        genT *= 0.01;

        for (int i = 0; i < popSize; i++)
        {
            thisChromo = population[i];
            thisChromo.selectionProbability(thisChromo.fitness() / genT);
        }

        for (int i = 0; i < maximumToSelect; i++)
        {
            rouletteSpin = getRandomNumber(0, 99);
            j = 0;
            selT = 0;
            done = false;
            while (!done)
            {
                thisChromo = population[j];
                selT += thisChromo.selectionProbability();
                if (selT >= rouletteSpin)
                {
                    if (j == 0)
                    {
                        thatChromo = population[j];
                    }
                    else if (j >= popSize - 1)
                    {
                        thatChromo = population[popSize - 1];
                    }
                    else
                    {
                        thatChromo = population[j - 1];
                    }
                    thatChromo.selected(true);
                    done = true;
                }
                else
                {
                    j++;
                }
            }
        }
        return;
    }

    //  This is where you can choose between options:

    //  To choose between crossover options, uncomment one of: 
    //     partiallyMappedCrossover(),
    //     positionBasedCrossover(), while keeping the other two commented out.


    private static void mating()
    {
        int getRand = 0;
        int parentA = 0;
        int parentB = 0;
        int newIndex1 = 0;
        int newIndex2 = 0;
        Chromosome newChromo1 = null;
        Chromosome newChromo2 = null;

        for (int i = 0; i < offSpring; i++)
        {
            parentA = chooseParent();
            // Test probability of mating.
            getRand = getRandomNumber(0, 100);
            if (getRand <= pMating * 100)
            {
                parentB = chooseParent(parentA);
                newChromo1 = new Chromosome();
                newChromo2 = new Chromosome();
                population.Add(newChromo1);
                newIndex1 = population.IndexOf(newChromo1);
                population.Add(newChromo2);
                newIndex2 = population.IndexOf(newChromo2);

                // Choose either, or both of these:
                partialCrossover(parentA, parentB, newIndex1, newIndex2);
                //positionBasedCrossover(parentA, parentB, newIndex1, newIndex2);

                if (childCount - 1 == nextMutation)
                {
                    exchangeMutation(newIndex1, 1);
                }
                else if (childCount == nextMutation)
                {
                    exchangeMutation(newIndex2, 1);
                }

                population[newIndex1].computeConflicts();
                population[newIndex2].computeConflicts();

                childCount += 2;

                // Schedule next mutation.
                if (childCount % (int)Math.Round(1.0 / rMutation) == 0)
                {
                    nextMutation = childCount + getRandomNumber(0, (int)Math.Round(1.0 / rMutation));
                }
            }
        } // i
        return;
    }

  private static  void partialCrossover(int chromA, int chromB, int child1, int child2)
    {
        int j = 0;
        int item1 = 0;
        int item2 = 0;
        int pos1 = 0;
        int pos2 = 0;
        Chromosome thisChromo = population[chromA];
        Chromosome thatChromo = population[chromB];
        Chromosome newChromo1 = population[child1];
        Chromosome newChromo2 = population[child2];
        int crossPoint1 = getRandomNumber(0, maxLength - 1);
        int crossPoint2 = getExclusiveRandomNumber(maxLength - 1, crossPoint1);

        if (crossPoint2 < crossPoint1)
        {
            j = crossPoint1;
            crossPoint1 = crossPoint2;
            crossPoint2 = j;
        }

        // Copy Parent genes to offspring.
        for (int i = 0; i < maxLength; i++)
        {
            newChromo1.data(i, thisChromo.data(i));
            newChromo2.data(i, thatChromo.data(i));
        }

        for (int i = crossPoint1; i <= crossPoint2; i++)
        {
            // Get the two items to swap.
            item1 = thisChromo.data(i);
            item2 = thatChromo.data(i);

            // Get the items//  positions in the offspring.
            for (j = 0; j < maxLength; j++)
            {
                if (newChromo1.data(j) == item1)
                {
                    pos1 = j;
                }
                else if (newChromo1.data(j) == item2)
                {
                    pos2 = j;
                }
            } // j

            // Swap them.
            if (item1 != item2)
            {
                newChromo1.data(pos1, item2);
                newChromo1.data(pos2, item1);
            }

            // Get the items//  positions in the offspring.
            for (j = 0; j < maxLength; j++)
            {
                if (newChromo2.data(j) == item2)
                {
                    pos1 = j;
                }
                else if (newChromo2.data(j) == item1)
                {
                    pos2 = j;
                }
            } // j

            // Swap them.
            if (item1 != item2)
            {
                newChromo2.data(pos1, item1);
                newChromo2.data(pos2, item2);
            }

        } // i
        return;
    }

   private static void positionCrossover(int chromA, int chromB, int child1, int child2)
    {
        int k = 0;
        int numPoints = 0;

        int[] tempArray1 = new int[maxLength];
        int[] tempArray2 = new int[maxLength];
        bool matchFound = false;
        Chromosome thisChromo = population[chromA];
        Chromosome thatChromo = population[chromB];
        Chromosome newChromo1 = population[child1];
        Chromosome newChromo2 = population[child2];

        // Choose and sort the crosspoints.
        numPoints = getRandomNumber(0, maxPBC);
        int[] crossPoints = new int[numPoints];
        int negativeNancy = -1;
        for (int i = 0; i < numPoints; i++)
        {
            crossPoints[i] = getRandomNumber(0, maxLength - negativeNancy, crossPoints);
        } // i

        // Get non-chosens from parent 2
        k = 0;
        for (int i = 0; i < maxLength; i++)
        {
            matchFound = false;
            for (int j = 0; j < numPoints; j++)
            {
                if (thatChromo.data(i) == thisChromo.data(crossPoints[j]))
                {
                    matchFound = true;
                }
            } // j
            if (matchFound == false)
            {
                tempArray1[k] = thatChromo.data(i);
                k++;
            }
        } // i

        // Insert chosens into child 1.
        for (int i = 0; i < numPoints; i++)
        {
            newChromo1.data(crossPoints[i], thisChromo.data(crossPoints[i]));
        }

        // Fill in non-chosens to child 1.
        k = 0;
        for (int i = 0; i < maxLength; i++)
        {
            matchFound = false;
            for (int j = 0; j < numPoints; j++)
            {
                if (i == crossPoints[j])
                {
                    matchFound = true;
                }
            } // j
            if (matchFound == false)
            {
                newChromo1.data(i, tempArray1[k]);
                k++;
            }
        } // i

        // Get non-chosens from parent 1
        k = 0;
        for (int i = 0; i < maxLength; i++)
        {
            matchFound = false;
            for (int j = 0; j < numPoints; j++)
            {
                if (thisChromo.data(i) == thatChromo.data(crossPoints[j]))
                {
                    matchFound = true;
                }
            } // j
            if (matchFound == false)
            {
                tempArray2[k] = thisChromo.data(i);
                k++;
            }
        } // i

        // Insert chosens into child 2.
        for (int i = 0; i < numPoints; i++)
        {
            newChromo2.data(crossPoints[i], thatChromo.data(crossPoints[i]));
        }

        // Fill in non-chosens to child 2.
        k = 0;
        for (int i = 0; i < maxLength; i++)
        {
            matchFound = false;
            for (int j = 0; j < numPoints; j++)
            {
                if (i == crossPoints[j])
                {
                    matchFound = true;
                }
            } // j
            if (matchFound == false)
            {
                newChromo2.data(i, tempArray2[k]);
                k++;
            }
        } // i
        return;
    }


   private static void exchangeMutation(int index, int exchanges)
    {
        int i = 0;
        int tempData = 0;
        Chromosome thisChromo = null;
        int gene1 = 0;
        int gene2 = 0;
        bool done = false;

        thisChromo = population[index];

        while (!done)
        {
            gene1 = getRandomNumber(0, maxLength - 1);
            gene2 = getExclusiveRandomNumber(maxLength - 1, gene1);

            // Exchange the chosen genes.
            tempData = thisChromo.data(gene1);
            thisChromo.data(gene1, thisChromo.data(gene2));
            thisChromo.data(gene2, tempData);

            if (i == exchanges)
            {
                done = true;
            }
            i++;
        }
        mutations++;
        return;
    }

   private static int chooseParent()
    {
        // Overloaded function, see also "chooseparent(ByVal parentA As Integer)".
        int parent = 0;
        Chromosome thisChromo = null;
        bool done = false;

        while (!done)
        {
            // Randomly choose an eligible parent.
            parent = getRandomNumber(0, population.Count - 1);
            thisChromo = population[parent];
            if (thisChromo.selected() == true)
            {
                done = true;
            }
        }

        return parent;
    }


    {
        // Overloaded function, see also "chooseparent()".
        int parent = 0;
        Chromosome thisChromo = null;
        bool done = false;

        while (!done)
        {
            // Randomly choose an eligible parent.
            parent = getRandomNumber(0, population.Count - 1);
            if (parent != parentA)
            {
                thisChromo = population[parent];
                if (thisChromo.selected() == true)
                {
                    done = true;
                }
            }
        }

        return parent;
    }

   private static void prepNextEpoch()
    {
        int popSize = 0;
        Chromosome thisChromo = null;

        // Reset flags for selected individuals.
        popSize = population.Count;
        for (int i = 0; i < popSize; i++)
        {
            thisChromo = population[i];
            thisChromo.selected(false);
        }
        return;
    }

   private static  void printSolution(Chromosome bestSolution)
    {

        string[][] board = RectangularArrays.ReturnRectangularStringArray(maxLength, maxLength);

        // Clear the board.
        for (int x = 0; x < maxLength; x++)
        {
            for (int y = 0; y < maxLength; y++)
            {
                board[x][y] = "";
            }
        }

        for (int x = 0; x < maxLength; x++)
        {
            board[x][bestSolution.data(x)] = "Q";
        }

        // Display the board.
        Console.WriteLine("Board:");
        for (int y = 0; y < maxLength; y++)
        {
            for (int x = 0; x < maxLength; x++)
            {
                if (string.ReferenceEquals(board[x][y], "Q"))
                {
                    Console.Write("Q ");
                }
                else
                {
                    Console.Write(". ");
                }
            }
            Console.Write("\n");
        }

        return;
    }


   private static int getRandomNumber(int low, int high)
    {
        return (int)Math.Round((high - low) * (new Random()).NextDouble() + low);
    }


   private static int getExclusiveRandomNumber(int high, int except)
    {
        bool done = false;
        int getRand = 0;

        while (!done)
        {
            getRand = (new Random()).Next(high);
            if (getRand != except)
            {
                done = true;
            }
        }

        return getRand;
    }

  private static  int getRandomNumber(int low, int high, int[] except)
    {
        bool done = false;
        int getRand = 0;

        if (high != low)
        {
            while (!done)
            {
                done = true;
                getRand = (int)Math.Round((high - low) * (new Random()).NextDouble() + low);
                for (int i = 0; i < except.Length; i++) //UBound(except)
                {
                    if (getRand == except[i])
                    {
                        done = false;
                    }
                } // i
            }
            return getRand;
        }
        else
        {
            return high; // or low (it doesn't matter).
        }
    }

  private static  int minimum()
    {
        // Returns an array index.
        int popSize = 0;
        Chromosome thisChromo = null;
        Chromosome thatChromo = null;
        int winner = 0;
        bool foundNewWinner = false;
        bool done = false;

        while (!done)
        {
            foundNewWinner = false;
            popSize = population.Count;
            for (int i = 0; i < popSize; i++)
            {
                if (i != winner)
                { // Avoid self-comparison.
                    thisChromo = population[i];
                    thatChromo = population[winner];
                    if (thisChromo.conflicts() < thatChromo.conflicts())
                    {
                        winner = i;
                        foundNewWinner = true;
                    }
                }
            }
            if (foundNewWinner == false)
            {
                done = true;
            }
        }
        return winner;
    }

     private static int maximum()
    {
        // Returns an array index.
        int popSize = 0;
        Chromosome thisChromo = null;
        Chromosome thatChromo = null;
        int winner = 0;
        bool foundNewWinner = false;
        bool done = false;

        while (!done)
        {
            foundNewWinner = false;
            popSize = population.Count;
            for (int i = 0; i < popSize; i++)
            {
                if (i != winner)
                { // Avoid self-comparison.
                    thisChromo = population[i];
                    thatChromo = population[winner];
                    if (thisChromo.conflicts() > thatChromo.conflicts())
                    {
                        winner = i;
                        foundNewWinner = true;
                    }
                }
            }
            if (foundNewWinner == false)
            {
                done = true;
            }
        }
        return winner;
    }

   private static void initializeChromosomes()
    {
        int shuffles = 0;
        Chromosome newChromo = null;
        int chromoIndex = 0;

        for (int i = 0; i < sSize; i++)
        {
            newChromo = new Chromosome();
            population.Add(newChromo);
            chromoIndex = population.IndexOf(newChromo);

            // Randomly choose the number of shuffles to perform.
            shuffles = getRandomNumber(minRandom, maxShuffles);

            exchangeMutation(chromoIndex, shuffles);

            population[chromoIndex].computeConflicts();

        }
        return;
    }

    private class Chromosome
    {
        internal int[] mData = new int[maxLength];
        internal double mFitness = 0.0;
        internal bool mSelected = false;
        internal double mSelectionProbability = 0.0;
        internal int mConflicts = 0;

        public Chromosome()
        {
            for (int i = 0; i < maxLength; i++)
            {
                this.mData[i] = i;
            }
            return;
        }

        public virtual void computeConflicts()
        {
            int x = 0;
            int y = 0;
            int tempx = 0;
            int tempy = 0;

            //string[][] board = new string[MAX_LENGTH][MAX_LENGTH];
            string[][] board = RectangularArrays.ReturnRectangularStringArray(maxLength, maxLength);
            int conflicts = 0;
            int[] dx = new int[] { -1, 1, -1, 1 };
            int[] dy = new int[] { -1, 1, 1, -1 };
            bool done = false;

            // Clear the board.
            for (int i = 0; i < maxLength; i++)
            {
                for (int j = 0; j < maxLength; j++)
                {
                    board[i][j] = "";
                }
            }

            for (int i = 0; i < maxLength; i++)
            {
                board[i][this.mData[i]] = "Q";
            }

            // Walk through each of the Queens and compute the number of conflicts.
            for (int i = 0; i < maxLength; i++)
            {
                x = i;
                y = this.mData[i];

                // Check diagonals.
                for (int j = 0; j <= 3; j++)
                {
                    tempx = x;
                    tempy = y;
                    done = false;
                    while (!done)
                    {
                        tempx += dx[j];
                        tempy += dy[j];
                        if ((tempx < 0 || tempx >= maxLength) || (tempy < 0 || tempy >= maxLength))
                        {
                            done = true;
                        }
                        else
                        {
                            if (board[tempx][tempy].ToString().ToUpper().Equals("Q"))// ignore the case of 2 strings

                            {
                                conflicts++;
                            }
                        }
                    }
                }
            }

            this.mConflicts = conflicts;
        }

        public virtual void conflicts(int value)
        {
            this.mConflicts = value;
            return;
        }

        public virtual int conflicts()
        {
            return this.mConflicts;
        }

        public virtual double selectionProbability()
        {
            return mSelectionProbability;
        }

        public virtual void selectionProbability(double SelProb)
        {
            mSelectionProbability = SelProb;
            return;
        }

        public virtual bool selected()
        {
            return mSelected;
        }


        public virtual void selected(bool sValue)
        {
            mSelected = sValue;
            return;
        }

        public virtual double fitness()
        {
            return mFitness;
        }


        public virtual void fitness(double score)
        {
            mFitness = score;
            return;
        }


        public virtual int data(int index)
        {
            return mData[index];
        }


        public virtual void data(int index, int value)
        {
            mData[index] = value;
            return;
        }
    } // Chromosome
     static void Main(string[] args)
    {
        algorithm();
        return;
    }
}
}

This is the second code here:

namespace NQueen1
{


    internal static class RectangularArrays
    {
        internal static string[][] ReturnRectangularStringArray(int size1, int size2)
        {
            string[][] newArray = new string[size1][];
            for (int array1 = 0; array1 < size1; array1++)
            {
                newArray[array1] = new string[size2];
            }

            return newArray;
        }
    }
}

THe Error:

Unhandled Exception: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) at System.Collections.Generic.List`1.get_Item(Int32 index) at NQueen1.Program.rouletteSelection() in C:\Users\Inspiron\Documents\coid\NQueen1\NQueen1\Program.cs:line 143 at NQueen1.Program.algorithm() in C:\Users\Inspiron\Documents\coid\NQueen1\NQueen1\Program.cs:line 56 at NQueen1.Program.Main(String[] args) in C:\Users\Inspiron\Documents\coid\NQueen1\NQueen1\Program.cs:line 841

I have no clue why its throwing off these errors I tried about almost everything I could think of to fix it

mjwills
  • 23,389
  • 6
  • 40
  • 63
  • 2
    That's a lot of code to go through, what is the expected output of said code? The errors you state you are getting are from accessing an out of bounds index in an array (like it says either below 0 or greater than the size of the array). I would check the lines mentioned for any array accessing and then put bounds checking on it and/or find out why an index is getting out of bounds. When I ran this code it was missing the function "private static int chooseParent(int parentA)" on line 474 and after fixing this, it compiled fine. However, it did not output anything. – Ryan Stonebraker Mar 15 '18 at 02:32
  • That is a runtime error, not a compiler error – mjwills Mar 15 '18 at 02:34
  • It would be awesome if you could provide a [mcve]. – mjwills Mar 15 '18 at 02:35
  • 1
    Possible duplicate of [What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?](https://stackoverflow.com/questions/20940979/what-is-an-indexoutofrangeexception-argumentoutofrangeexception-and-how-do-i-f) – mjwills Mar 15 '18 at 02:35

1 Answers1

1

This is just a random guess.

My Spidey Senses tells me thisChromo = population[j] is probably overrunning the size of array, i.e. its in a while loop with j++ and there is no real bounds checking

private static void rouletteSelection()
{
    ...
    for (int i = 0; i < maximumToSelect; i++)
    {
    ...
        while (!done)
        {
            thisChromo = population[j]; 
            ...
            j++;

If this is the problem, I'd consider the possibility that j will be larger than population.Length and therefore breaking out of the loop; using an if statement; or just refactoring this logic

Tips for your future questions

  • If you have a runtime error, show us the line of code it has the error on
  • Pasting code is vital, however pasting too much is annoying and hard to read
  • If you paste code, at least try to format it
  • Learn to use the debugger and breakpoints (see: How to use the Debugger, Using Breakpoints).
halfer
  • 19,824
  • 17
  • 99
  • 186
TheGeneral
  • 79,002
  • 9
  • 103
  • 141