我发送了一个对象列表List<solutions>
&#34; _solutions&#34;作为参数的方法,然后我将此参数复制到另一个名为&#34; SOLUTIONS &#34;的列表中。并对SOLUTIONS进行一些更改,最后返回SOLUTIONS。但是当我更改SOLUTIONS时,_solution将被更改。我不想改变_solutions。
例如,在行SOLUTIONS[pp].Route.Clear();
之后,当pp = 0时,_solution [0]。路径将会清晰。
static List<solutions> CrossOverB(List<solutions> _Solutions)
{
List<solutions> SOLUTIONS = new List<solutions>();
SOLUTIONS.AddRange(_Solutions);
int pp = 0;
List<int> Team1;
List<int> Team2;
List<int> TempOff1;
List<int> TempOff2;
int index1 = 0;
double Time1 = int.MaxValue, Time2 = int.MaxValue;
while (pp < PopulationSize)
{
Team1 = new List<int>();
Team2 = new List<int>();
TempOff1 = new List<int>();
TempOff2 = new List<int>();
index1 = 0;
Time1 = int.MaxValue;
Time2 = int.MaxValue;
int[] MinMax = new int[2];
int maxindex = 0, minindex = 0;
MinMax = FindMaximumMinimumTeam(SOLUTIONS[pp].Route);
minindex = MinMax[0];
maxindex = MinMax[1];
//extract maximum team from
Team1 = ExtractTeamFromSolution(SOLUTIONS[pp].Route, maxindex);
//remove start and end city
Team1.RemoveAt(0);
Team1.RemoveAt(Team1.Count - 1);
Team2 = ExtractTeamFromSolution(SOLUTIONS[pp].Route, minindex);
Team2.RemoveAt(0);
Team2.RemoveAt(Team2.Count - 1);
//add team2 to team1
//all cities are in team1
Team1.AddRange(Team2);
Team2.Clear();
//add other teams(except max and min team) to the team2
for (int i = 1; i < NoOfTeams + 1; i++)
{
if (i != maxindex && i != minindex)
{
Team2.AddRange(ExtractTeamFromSolution(SOLUTIONS[pp].Route, i));
}
}
TempOff1.Add(StartCity);
TempOff1.Add(endCity);
TempOff2.Add(StartCity);
TempOff2.Add(endCity);
//index1 = TempOff1.Count - 1;
//index2 = TempOff2.Count - 1;
while (index1 != Team1.Count)
{
Time1 = int.MaxValue;
Time2 = int.MaxValue;
//fill off1
//i want to add team1[index1] to the off1 or off2 righ befor the end city
if (CalculateTeamTime(TempOff1, Team1.ElementAt(index1), TempOff1.Count - 2) < TMAX)
{
Time1 = TimeTable[TempOff1.ElementAt(TempOff1.Count - 2)][Team1.ElementAt(index1)];
}
if (CalculateTeamTime(TempOff2, Team1.ElementAt(index1), TempOff2.Count - 2) < TMAX)
{
Time2 = TimeTable[TempOff2.ElementAt(TempOff2.Count - 2)][Team1.ElementAt(index1)];
}
//compare time1 and time2 for the winner
if (Time1 <= Time2
&& TempOff1.Contains(Team1.ElementAt(index1)) == false
&& TempOff2.Contains(Team1.ElementAt(index1)) == false
&& Team2.Contains(Team1.ElementAt(index1)) == false
&& CalculateTeamTime(TempOff1, Team1.ElementAt(index1), TempOff1.Count - 2) < TMAX)//fill off1
{
TempOff1.Insert(TempOff1.Count - 1, Team1.ElementAt(index1));
index1++;
}
else if (Time1 >= Time2
&& TempOff2.Contains(Team1.ElementAt(index1)) == false
&& TempOff1.Contains(Team1.ElementAt(index1)) == false
&& Team2.Contains(Team1.ElementAt(index1)) == false
&& CalculateTeamTime(TempOff2, Team1.ElementAt(index1), TempOff2.Count - 2) < TMAX)//fill off2
{
TempOff2.Insert(TempOff2.Count - 1, Team1.ElementAt(index1));
index1++;
}
else// off1 and off2 do not accept the city. so i reject the city
{
index1++;
}// of else
if (CalculateTeamTime(TempOff2)>TMAX)
{
Console.WriteLine();
}
}// of while
SOLUTIONS[pp].Route.Clear();
SOLUTIONS[pp].Route.AddRange(TempOff1);
SOLUTIONS[pp].Route.AddRange(TempOff2);
SOLUTIONS[pp].Route.AddRange(Team2);
pp++;
}
return SOLUTIONS;
}
答案 0 :(得分:1)
我猜solutions
是一个班级,对吗?类是引用类型,即您不对实际对象进行操作,而是对这些对象的引用。
当您调用SOLUTIONS.AddRange(_Solutions);
时,您并没有真正复制对象,但是您只是复制对_Solutions
中对象的引用并将它们存储在SOLUTIONS
中,但对象仍然存在同样的。 _Solutions
中的第一个对象与<{1}}中的第一个对象完全相同(依此类推),而不是保存相同数据的不同对象。
您必须创建对象的深层副本才能解决此问题。例如,您可以在SOLUTIONS
类
Copy
solutions
然后更改行以将项目复制到
solutions Copy()
{
return new solutions
{
[... copy all fields here]
};
}
您将拥有一个包含全新对象的全新列表,而不仅仅是旧列表中无聊的旧对象。
答案 1 :(得分:0)
您实际上正在复制对_Solutions
列表中元素的引用。从_Solutions
中的元素查询信息时,元素级别的任何更改(元素中的某些属性)也将可见。
您的代码
List<solutions> SOLUTIONS = new List<solutions>();
SOLUTIONS.AddRange(_Solutions);
只能确保你有一个不同的引用列表(当你想要迭代时可能很有用 - foreach
- 并且在原始列表中进行更改,这是不能直接完成的。)
您已经深深克隆了您的列表,实际上正在为每个元素生成对象的新实例,正如bradbury9
已建议的那样(检查here)。