我正在用 C# 编写一个简单的 hillclimber 算法,并正在尝试以下方法:
获取初始解决方案
将解决方案复制到新对象
应用算法复制
比较初始解的obj值和copy的obj值
如果更好 - 复制回初始解决方案。
我知道这个主题已经在之前的帖子中被触及并尝试实现那里的建议 - 使用 IClonable 类。这是我尝试过的:
我的解决方案类:
class Solution : ICloneable
{
public Dictionary<Room, List<Patient>> solution { get; set; }
public Solution()
{
solution = new Dictionary<Room, List<Patient>>();
}
public object Clone()
{
return this.MemberwiseClone();
}
}
算法:
public static void swap (Solution solution, Output input, Random rand)
{
Solution intSoln = new Solution();
intSoln = (Solution)solution.Clone();
//Moving things around in intSoln here
Console.WriteLine("new solution = " + objValue(intSoln, input));
Console.WriteLine("old solution = " + objValue(solution, input));
if (objValue(intSoln, input) < objValue(solution, input))
{
solution = (Solution)intSoln.Clone();
}
}
查看新旧解决方案的打印输出,它们总是相同的,这意味着代码显然仍然是通过引用复制的。我很困惑,不知道该怎么办。任何帮助将不胜感激。
MemberwiseClone
将进行浅拷贝,这意味着您将获得一个新实例,其字段具有与初始对象相同的引用。
您想做一个深层复制。这是一个多了一层的副本:
public object Clone()
{
var copy = new Solution();
foreach (var pair in solution)
copy.solution.Add(pair.Key, pair.Value);
return copy;
}
这将复制字典,但它的键和值将仍指向相同的实例。所以你可以用类似的东西执行更深的复制:
public object Clone()
{
var copy = new Solution();
foreach (var pair in solution)
copy.solution.Add(new Room(pair.Key), pair.Value.ToList());
return copy;
}
或者:
public object Clone()
{
var copy = new Solution();
foreach (var pair in solution)
copy.solution.Add(new Room(pair.Key), pair.Value.Select(i => new Patient(i)).ToList());
return copy;
}
为此,您需要为 Room
和 Patient
编写一些复制构造函数。希望你明白了。
我是一名优秀的程序员,十分优秀!