我的代码显示编译器错误,我不知道为什么即使代码似乎是正确的

时间:2018-03-15 01:43:43

标签: c# n-queens

好的所以我在c#中完成了我的代码n queens genetics,但即使我多次更改了代码,我仍然会收到这些编译错误

 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;
    }
}
}

这是第二个代码:

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;
        }
    }
}

错误:

  

未处理的异常:System.ArgumentOutOfRangeException:索引超出范围。必须是非负数且小于集合的大小。   参数名称:index      在System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument参数,ExceptionResource资源)      在System.Collections.Generic.List`1.get_Item(Int32索引)      在NQueen1.Program.rouletteSelection()在C:\ Users \ Inspiron \ Documents \ coid \ NQueen1 \ NQueen1 \ Program.cs:第143行      在NQueen1.Program.algorithm()在C:\ Users \ Inspiron \ Documents \ coid \ NQueen1 \ NQueen1 \ Program.cs:第56行      at NQueen1.Program.Main(String [] args)在C:\ Users \ Inspiron \ Documents \ coid \ NQueen1 \ NQueen1 \ Program.cs:841行

我不知道为什么它会抛弃这些错误我尝试了几乎所有我想到的修复它

1 个答案:

答案 0 :(得分:1)

这只是随机猜测,

但是我的 Spidey Senses 告诉我thisChromo = population[j]可能超出了array的大小,即它在while循环中j++和没有真正的界限检查

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

如果这是问题,则id会考虑j大于population.Lenth的可能性,从而突破循环;使用if语句;或者只是重构这个逻辑

您未来提问的提示

  • 如果您遇到运行时错误,请向我们显示
  • 上出现错误的代码行
  • 粘贴代码至关重要,但粘贴太多令人讨厌且难以阅读
  • 如果您粘贴代码,至少要尝试格式化

  • 了解如何使用调试器和断点How to use the DebuggerUsing Breakpoints