簡體   English   中英

我的代碼顯示編譯器錯誤,即使代碼看起來正確,我也不知道為什么

[英]My code is showing compiler erros and I dont know why even though the code seems correct

好的,所以我在 c# 中完成了我的代碼 n 皇后遺傳學,但即使我多次更改代碼,我仍然收到這些編譯器錯誤

 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:索引超出范圍。 必須是非負數且小於集合的大小。 參數名稱: System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument 參數,ExceptionResource 資源)處的索引 System.Collections.Generic.List`1.get_Item(Int32 索引)在 Z0D61F8370CAD1D412F80B84 中的 NQueen1.Program.rouletteSelection() 處\coid\NQueen1\NQueen1\Program.cs:NQueen1.Program.algorithm() 中 C:\Users\Inspiron\Documents\coid\NQueen1\NQueen1\Program.cs 的第 143 行:NQueen1.Program.Main 的第 56 行( C:\Users\Inspiron\Documents\coid\NQueen1\NQueen1\Program.cs:line 841 中的 String[] args)

我不知道為什么它會拋出這些錯誤我嘗試了幾乎所有我能想到的修復它

這只是一個隨機猜測。

我的Spidey Senses告訴我thisChromo = population[j]可能超出了array的大小,即它在一個帶有j++while循環中並且沒有真正的邊界檢查

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

如果這是問題所在,我會考慮j大於population.Length並因此跳出循環的可能性; 使用if語句; 或者只是重構這個邏輯

對您未來問題的提示

  • 如果您有運行時錯誤,請向我們展示出現錯誤的代碼行
  • 粘貼代碼很重要,但是粘貼太多會煩人且難以閱讀
  • 如果您粘貼代碼,至少嘗試格式化它
  • 學習使用調試器和斷點(請參閱:如何使用調試器使用斷點)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM