0

我有遗传算法轮盘的代码。当我的迭代次数超过 1000 次时,我的程序显示错误,但当迭代次数少于 1000 次时,它的效果非常好。这是我的代码

private double[] roulleteWheel(double[] nilaiFitnessRil)
    {
        double[] resultRW = new double[nilaiFitnessRil.GetLength(0)];
        double[] probKromosom = new double[nilaiFitnessRil.GetLength(0)];
        double[] probKumulatif = new double[nilaiFitnessRil.GetLength(0)];
        double pilih=0;
        Random random = new Random();
        double rnd;
        double total = 0;
        double temp = 0;
        //count total fitness
        for (int i = 0; i < nilaiFitnessRil.Length; i++)
        {
            total += nilaiFitnessRil[i];

        }
        listBox1.Items.Add(string.Format("total fitness adalah {0}",total));
        //count probability for each chromosome
        listBox1.Items.Add("result of probabilty for each chromosome");
        for (int i = 0; i < nilaiFitnessRil.Length; i++)
        {
            probKromosom[i] = Math.Round(nilaiFitnessRil[i] / total, 4);
            listBox1.Items.Add(probKromosom[i].ToString());
        }
        //count cumulative probability
        listBox1.Items.Add("result of cumulative probabilty ");
        for (int i = 0; i < probKromosom.Length; i++)
        {
            temp += probKromosom[i];
            probKumulatif[i] = temp;
            listBox1.Items.Add(probKumulatif[i].ToString());
        }
        //selecting a chromosome by its cumulative probability with a random value

        listBox1.Items.Add(" roullete wheel");
        for (int n = 0; n < resultRil.Length; n++)
        {
            rnd = random.NextDouble() * 1.0 - 0.0;
            //listBox1.Items.Add(rnd.ToString());
            for (int i = 0; i < probKumulatif.Length; i++)
            {
           //this is where the Index was outside the bounds of the array appear 
                if (probKumulatif[i] <= rnd && probKumulatif[i + 1] > rnd ) 
                {
                    pilih = resultRil[i + 1];
                }
                else if ( rnd <= probKumulatif[0])
                {
                    pilih = resultRil[0];
                }


            }
            resultRil[n] = pilih;
            resultRW[n] = resultRil[n];
        }
        PrintArray(resultRW, listBox1);
            return resultRW;
    }

这是程序因 Index 超出数组范围而终止的地方

 if (probKumulatif[i] <= rnd && probKumulatif[i + 1] > rnd ) 
                {
                    pilih = resultRil[i + 1];
                }
                else if ( rnd <= probKumulatif[0])
                {
                    pilih = resultRil[0];
                }
4

4 回答 4

3

你得到一个超出范围的索引,因为i + 1当你循环遍历每个项目时,你在循环中引用。因此,您将尝试访问的最后一次迭代probKumulatif[probKumulatif.Length]不存在。尝试循环到probKumulatif.Length - 1

// *** On this line ***
for (int i = 0; i < probKumulatif.Length - 1; i++)
{
    //this is where the Index was outside the bounds of the array appear 
    if (probKumulatif[i] <= rnd && probKumulatif[i + 1] > rnd ) 
    {
        pilih = resultRil[i + 1];
    }
    else if ( rnd <= probKumulatif[0])
    {
        pilih = resultRil[0];
    }
}

您还指的是resultRilusingi和 not n。如果您的意思是n,则可以在访问时应用与上述相同的方法resultRil[i + 1]

for (int n = 0; n < resultRil.Length - 1; n++)
{
    ...
}

您可能需要参考在内部循环中resultRil使用n

pilih = resultRil[n + 1];
于 2013-04-23T03:38:41.137 回答
1
for (int i = 0; i < probKumulatif.Length; i++)
{
    //this is where the Index was outside the bounds of the array appear 
    if (probKumulatif[i] <= rnd && probKumulatif[i + 1] > rnd )

这个循环的最后一次迭代会发生什么,什么时候i == probKumulatif.Length - 1

如果probKumulatif[i] <= rnd为真,那么probKumulatif[i + 1] > rnd将被评估,并且因为i == probKumulatif.Length - 1,那么i + 1 == probKumulatif.Length- 所以你尝试访问probKumulatif[probKumulatif.Length],这会导致你的异常!

请注意,由于rnd随机的,这只会在某些时候发生,运行次数越多,概率越大!

于 2013-04-23T03:39:04.470 回答
0

简单的。因为在循环的最后一次运行中, probKumulatif[i + 1] 试图达到不允许的 probKumulatif[probKumulatif.Length]。您可以达到的最大索引是 probKumulatif[probKumulatif.Length-1]。请在发布之前尝试调试您的代码。

于 2013-04-23T03:42:28.123 回答
0

发生错误是因为您尝试访问超出其范围的索引处的数组。您可以简单地检查如下:

if (probKumulatif[i] <= rnd && (probKumulatif.Length >= i+1 && probKumulatif[i + 1] > rnd) ) 
{
    pilih = resultRil[i + 1];
 }
else if ( rnd <= probKumulatif[0])
{
    pilih = resultRil[0];
}

但我建议改为使用 for 循环:

for (int i = 0; i < probKumulatif.Length-1; i++)
{
//Keep it the same.
}
于 2013-04-23T03:52:50.383 回答