我试图端口this Genetic Algorithm, ,我做了一个递归函数从一代推进到另一代。但是,因为我是C#中的新递归(一般情况下),当代数太多(大约4500)时,我显然遇到了StackOverflowException。优雅的方法来防止递归中的StackOverflow
为了解决这个问题,我让Generation()返回一个bool,所以当遗传算法达到最大适应度(目标)时,它会返回true。否则它返回Generation()。
如果它即将溢出(代> 4500),则返回false。
Now在Main()中,为了使Generation()继续运行直到它返回true,我使用一个while循环,因此它将在递归开始之前一直运行,直到它完成。
这比做Task.Run更有效率,所以我采用了这种方法。
这是一个很好的做法吗?有没有更好的方法来防止StackOverflows而不牺牲性能?
Population.cs:
class Population
{
public int GenerationNumber { get; private set; }
public int TotalGenerationNumber { get; private set; }
public const int StackGenerationLimit = 4500;
public Population()
{
GenerationNumber = 0;
TotalGenerationNumber = 0;
}
public bool Generation()
{
// Work
// if(HasReachedGoal) return true;
GenerationNumber++;
if(GenerationNumber > StackGenerationLimit)
{
return false;
} else
{
return Generation();
}
}
public void ResetStack()
{
TotalGenerationNumber += GenerationNumber; // I store the total number of generation for information purposes
GenerationNumber = 0; // Reset the recursion depth value
}
}
Program.cs的
class Program
{
static void Main(string[] args)
{
Population population = new Population();
while (!population.Generation()) // Until it reaches its goal
{
population.ResetStack();
}
Console.WriteLine("End. Generations: " + population.TotalGenerationNumber);
}
}
通常你不必保持递归方法运行 – EpicKip
如果你得到了一个stackoverflow的点,你应该考虑改变方法到一个非递归的方法。在这种情况下,它实际上非常简单,因为算法基本上是“配对生成,变异代,过滤器生成,重复”。听起来更像是一个循环,而不是递归。事实上,这在性能方面比递归更好(如果正确实施)。 – Paul