Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么要列出<;T>;。删除范围(索引、计数)在索引之前更改值?_C#_.net_List_Ienumerable_Genetic Algorithm - Fatal编程技术网

C# 为什么要列出<;T>;。删除范围(索引、计数)在索引之前更改值?

C# 为什么要列出<;T>;。删除范围(索引、计数)在索引之前更改值?,c#,.net,list,ienumerable,genetic-algorithm,C#,.net,List,Ienumerable,Genetic Algorithm,我正在实现一个经典的遗传算法。在交叉阶段,我发现了一些奇怪的行为 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.Cou

我正在实现一个经典的遗传算法。在交叉阶段,我发现了一些奇怪的行为

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);
        }
    }
}
专用静态无效交叉(参考列表对)
{
var random=新的random();
//要调试这个吗
foreach(成对变量对)
{
for(var i=0;i
每个染色体包含12个基因。它从一个随机定义的位点开始交换同源部分。例如,如果我们有
locus=8
crossoverLength=4
,我们首先使用
removange
基因[8]
基因[11]
,然后使用
AddRange
从另一个染色体添加基因

有时会发生一些奇怪的事情:当我们使用
RemoveRange
时,
基因[7]
(在本例中)将其值从0更改为1或从1更改为0。它不是每次迭代都会发生,有时一切都很好。我注意到,对于
locus=7..11
,这种情况更为常见

它不会对算法造成太大的伤害(只是更多的突变:D)。但有人知道为什么它会颠倒价值观吗

更新:

非常感谢BJ Myers给出的无可争议的答案。
其他人,谁将阅读这篇文章后,可能会感兴趣,为什么会发生。解释得很好。

RemoveRange
没有更改指定索引之前的值。这似乎是因为您的索引被关闭了1

请看这一行:

pair.First.Chromosomes[i].Genes.RemoveRange(locus - 1, crossoverLength);
如果我们假设(如您的示例所示)
locus=8
,因此
crossoverLength=4
,那么所需的行为将是通过
[11]
删除索引为
[8]
的元素。但是,由于您已经从
轨迹中减去了一个
,因此将
7
作为第一个参数传递给
RemoveRange
,从而通过
[10]
删除元素
[7]

对于调用
RemoveRange
,正确的代码不应包含
-1
偏移量:

pair.First.Chromosomes[i].Genes.RemoveRange(locus, crossoverLength);

您认为元素
[7]
改变的行为实际上是元素
[7]
通过
[10]
被移除的结果,而元素先前位于
[11]
的位置向下移动到
[7]
。如果您的“基因”始终是二进制的,则值有50/50的可能性会因
RemoveRange
调用而“更改”。

RemoveRange
不会更改指定索引之前的值。这似乎是因为您的索引被关闭了1

请看这一行:

pair.First.Chromosomes[i].Genes.RemoveRange(locus - 1, crossoverLength);
如果我们假设(如您的示例所示)
locus=8
,因此
crossoverLength=4
,那么所需的行为将是通过
[11]
删除索引为
[8]
的元素。但是,由于您已经从
轨迹中减去了一个
,因此将
7
作为第一个参数传递给
RemoveRange
,从而通过
[10]
删除元素
[7]

对于调用
RemoveRange
,正确的代码不应包含
-1
偏移量:

pair.First.Chromosomes[i].Genes.RemoveRange(locus, crossoverLength);
您认为元素
[7]
改变的行为实际上是元素
[7]
通过
[10]
被移除的结果,而元素先前位于
[11]
的位置向下移动到
[7]
。如果您的“基因”始终是二进制的,那么值有50/50的可能性会因
RemoveRange
调用而“改变”