저는 고전적인 유전자 알고리즘을 구현하고 있습니다. 크로스 오버 단계에서 나는 이상한 행동을 찾고있다.Why List <T> .RemoveRange (index, count)는 인덱스 이전의 값을 변경합니까?
private static void Crossover(ref List<CrossoverPair> pairs)
{
var random = new Random();
//TODO debug this
foreach (var pair in pairs)
{
for (var i = 0; i < pair.First.Chromosomes.Count; i++)
{
var locus = random.Next(1, 12);
var crossoverLength = pair.First.Chromosomes[i].Genes.Count - locus;
var swapFirst = pair.First.Chromosomes[i].Genes.Skip(locus).Take(crossoverLength).ToList();
var swapSecond = pair.Second.Chromosomes[i].Genes.Skip(locus).Take(crossoverLength).ToList();
pair.First.Chromosomes[i].Genes.RemoveRange(locus - 1, crossoverLength);
pair.First.Chromosomes[i].Genes.AddRange(swapSecond);
pair.Second.Chromosomes[i].Genes.RemoveRange(locus - 1, crossoverLength);
pair.Second.Chromosomes[i].Genes.AddRange(swapFirst);
}
}
}
각 염색체는 12 개의 유전자를 포함합니다. 그것은 무작위로 정의 된 궤적에서 시작하여 상동 부분들을 교환합니다. 예를 들어 locus = 8
과 crossoverLength = 4
이있는 경우 먼저 Genes[8]
에서 Genes[11]
까지 유전자를 제거하고 RemoveRange
을 사용하고 AddRange
을 사용하여 다른 염색체의 유전자를 추가합니다.
때로는 이상한 일이 발생합니다. RemoveRange
을 사용하면 Genes[7]
(이 인스턴스의 경우) 값이 0에서 1 또는 1에서 0으로 변경됩니다. 각 반복마다 발생하지는 않지만 때로는 모든 것이 정상적으로 작동합니다. 나는 그것이 더 자주 locus = 7..11
에 대해 발생하는 것으로 나타났습니다.
알고리즘을 너무 많이 손상시키지 않습니다 (단지 더 많은 돌연변이가 있습니다 : D). 하지만 왜 사람들이 가치를 왜곡하는지 아는 사람이 있습니까?
업데이트 :
감사 논박 할 수없는 답변 BJ 마이어스에 많은. 나중에이 게시물을 읽는 모든 사람들이 관심을 가질 것입니다. 왜 그렇게됩니까? 그것은 좋은 here 설명되어 있습니다.