C# 列表<&燃气轮机;集合成员不在时发生更改';我不应该
我在控制台项目的主方法中填充了一个列表。我将这个群体传递给一个方法,该方法旨在获取群体中的两个成员,并对它们进行分解和重新组合,以创建两个新的唯一成员,这些成员稍后将添加到群体中 但是,当我操纵两个原始成员以创建两个新的唯一成员时,两个原始成员会随着初始填充的变化而变化(从而改变初始填充)。这意味着当我添加新成员时,列表中会出现重复条目 我没有做任何过于复杂的事情,我想我只是在做一些愚蠢的事情 有人知道为什么会发生这种情况吗? 下面是调用的方法,用于选择初始的两个人口成员:C# 列表<&燃气轮机;集合成员不在时发生更改';我不应该,c#,.net,list,data-structures,C#,.net,List,Data Structures,我在控制台项目的主方法中填充了一个列表。我将这个群体传递给一个方法,该方法旨在获取群体中的两个成员,并对它们进行分解和重新组合,以创建两个新的唯一成员,这些成员稍后将添加到群体中 但是,当我操纵两个原始成员以创建两个新的唯一成员时,两个原始成员会随着初始填充的变化而变化(从而改变初始填充)。这意味着当我添加新成员时,列表中会出现重复条目 我没有做任何过于复杂的事情,我想我只是在做一些愚蠢的事情 有人知道为什么会发生这种情况吗? 下面是调用的方法,用于选择初始的两个人口成员: public sta
public static List<Chromosome<Gene>> runEpoch(Random rand, List<Chromosome<Gene>> population, SelectionMethod selectionMethod)
{
int populationSize = population.Count;
int selectionCount = (int)Math.Truncate((population.Count * 0.75));
if (selectionMethod == SelectionMethod.Tournament)
{
for (int i = 0; i < selectionCount; i++)
{
Chromosome<Gene> parent = selection.runTournament(rand, population);
Chromosome<Gene> parentTwo = selection.runTournament(rand, population);
//Checks for the presence of incestuous mating. In some cases incestuous mating causes a stack overflow to occur that the program can not recover from
if (parent != parentTwo)
{
//where runGeneOperators calls the crossOver method directly
offSpring = runGeneOperators(rand, parent, parentTwo);
}
else
{
i--;
}
}
}
else
{
//NSGAII
}
//fixPopulation is meant to sort and remove any excess members
return fixPopulation(rand, population, selectionMethod, populationSize); ;
}
公共静态列表运行期(随机随机随机、列表填充、SelectionMethod SelectionMethod)
{
int populationSize=population.Count;
int selectionCount=(int)Math.Truncate((population.Count*0.75));
如果(selectionMethod==selectionMethod.Tornament)
{
对于(int i=0;i
下面是创建两个新的唯一成员的代码:
public List<Chromosome<Gene>> crossOver(Random rand, Chromosome<Gene> parentOne, Chromosome<Gene> parentTwo)
{
List<Chromosome<Gene>> offSpring = new List<Chromosome<Gene>>();
int crossPtOne = rand.Next(0, parentOne.Length);
int crossPtTwo = rand.Next(0, parentTwo.Length);
if ((crossPtOne == 0) && (crossPtTwo == 0))
{
offSpring.Add(parentOne);
offSpring.Add(parentTwo);
return offSpring;
}
else
{
GeneNode<Gene> fragOne = parentOne.Children[crossPtOne];
GeneNode<Gene> fragTwo = parentTwo.Children[crossPtTwo];
crossOverPoint = crossPtOne;
GeneNode<Gene> genotype = performCrossOver(parentOne.Genotype, fragTwo);
success = false;
parentOne.repair(genotype);
offSpring.Add(parentOne);
crossOverPoint = crossPtTwo;
GeneNode<Gene> genotype2 = performCrossOver(parentTwo.Genotype, fragOne);
success = false;
parentTwo.repair(genotype2);
offSpring.Add(parentTwo);
}
return offSpring;
}
private GeneNode<Gene> performCrossOver(GeneNode<Gene> tree, GeneNode<Gene> frag)
{
if (tree != null)
{
if (crossOverPoint > 0)
{
if (!success && tree.Left != null)
{
crossOverPoint--;
tree.Children[0] = performCrossOver(tree.Left, frag);
}
}
if (crossOverPoint > 0)
{
if (!success && tree.Right != null)
{
crossOverPoint--;
tree.Children[1] = performCrossOver(tree.Right, frag);
}
}
}
if (!success)
{
if (crossOverPoint == 0)
{
success = true;
return frag;
}
}
return tree;
}
public List交叉(随机随机随机、染色体parentOne、染色体parentTwo)
{
列表子代=新列表();
int crossPtOne=rand.Next(0,parentOne.Length);
int crossPtTwo=rand.Next(0,parentTwo.Length);
如果((crossPtOne==0)和&(Crossptwo==0))
{
添加(parentOne);
添加(parentTwo);
返回后代;
}
其他的
{
GeneNode fragOne=parentOne.Children[crossPtOne];
GeneNode fragTwo=parentTwo.Children[crossPtTwo];
交叉重叠点=交叉点;
GeneNode基因型=性能交叉(parentOne.genetic,fragTwo);
成功=错误;
修复(基因型);
添加(parentOne);
交叉重叠点=交叉点;
GeneNode基因型2=性能交叉(parentTwo.基因型,fragOne);
成功=错误;
父母2.修复(基因型2);
添加(parentTwo);
}
返回后代;
}
专用GeneNode performCrossOver(GeneNode树,GeneNode框架)
{
如果(树!=null)
{
如果(交叉重叠点>0)
{
如果(!success&&tree.Left!=null)
{
交叉重叠点--;
tree.Children[0]=performCrossOver(tree.Left,frag);
}
}
如果(交叉重叠点>0)
{
如果(!success&&tree.Right!=null)
{
交叉重叠点--;
tree.Children[1]=performCrossOver(tree.Right,frag);
}
}
}
如果(!成功)
{
如果(交叉重叠==0)
{
成功=真实;
返回碎片;
}
}
回归树;
}
在C#中,对象是引用类型,这意味着向集合中添加内容只会添加引用。如果使用相同的引用(在本例中为“原始”对象)操作变量,则指向该对象的所有引用也将更改。您需要以某种方式复制对象以拥有不同的对象并对其进行操作。在C#中,对象是引用类型,这意味着向集合中添加某些内容只会添加引用。如果使用相同的引用(在本例中为“原始”对象)操作变量,则指向该对象的所有引用也将更改。您需要以某种方式复制对象,以拥有不同的对象并对其进行操作。要在不改变对象的情况下操作集合和其中的对象,您需要对集合及其包含的对象进行深度克隆,因此,您可以在不更改克隆的情况下更改列表A。如果您只想更改列表中的某个对象,则需要对列表中的对象进行深度克隆,然后更改深度克隆。这将确保您的原件未被更改
应该在对象上实现该接口,以使其可关闭
编辑:根据Henk的评论,您应该只实现自己的复制方法,而不实现IClonable接口,如文章所述
对象的克隆有两种形式,深和浅
浅:这种形式的克隆创建一个新对象,然后将当前对象的非静态字段复制到新对象。如果字段是值类型,则执行该字段的逐位复制。如果字段是引用类型,则复制引用,但不复制引用对象;因此,原始对象及其克隆引用同一对象<
private List<Gene> initialGeneList;
public List<Gene> InitialGenes
{
get { return new List<Gene>(initialGeneList); } // return a new list
}
string s = "Hello World";
s.Substring(0,5); // s unchanged. still 'Hello World'
s = s.Substring(0,5); // s changed. now 'Hello'
string s1 = "Hello";
string s2 = string.Concat("He","l", "lo");
bool equal = s1.Equals(s2);
bool referenceEqual = object.ReferenceEquals(s1, s2);
// s1 == s2 => True, Reference Equal => False
Console.Write("s1 == s2 => {0}, Reference Equal => {1}", equal, referenceEqual);