C#列表对象在不调试时被重用
我目前遇到一个问题,我试图生成一个随机旅游对象列表(旅行推销员)。当我调试代码时,一切正常,但是当我只是运行代码(甚至运行代码的这一部分)时,我的列表中充满了相同对象的所有内容C#列表对象在不调试时被重用,c#,list,loops,C#,List,Loops,我目前遇到一个问题,我试图生成一个随机旅游对象列表(旅行推销员)。当我调试代码时,一切正常,但是当我只是运行代码(甚至运行代码的这一部分)时,我的列表中充满了相同对象的所有内容 for (int i = 0; i < populationSize; i++) { var newTour = new Tour(distanceCalculator); newTour.GenerateIndividual(); this.Tours[i] = newTour;
for (int i = 0; i < populationSize; i++)
{
var newTour = new Tour(distanceCalculator);
newTour.GenerateIndividual();
this.Tours[i] = newTour;
newTour = null;
}
我知道洗牌是有效的,因为路径总是以随机顺序排列。问题是,只有在调试到for循环中时,路径中的巡更才会更新。例如,如果mypopulationSize
为10,并且我调试了5次,我将有一个包含5个随机巡更的巡更的总体,那么最后5个巡更将与我上次调试的巡更相同。这里发生了什么?newTour
对象是否仅在我调试时被重置,但当我运行C#时,它反复使用同一个对象?“那么最后5次巡更将与我上次调试的相同”似乎表明洗牌方法不起作用
我猜Shuffle
方法每次调用时都会调用new Random()
,因为这段代码非常短,所以每次都会生成相同的结果。在“调试”中,您会减慢速度,Shuffle
似乎工作正常,但我不这么认为
(奇怪的是,为什么最后5个元素与第5个元素相同,我不确定那里发生了什么)。问题确实出在我的洗牌方法中。正如@mayu所指出的,每次调用我都使用一个新的随机对象,它使用相同的种子,每次都给我相同的随机数。而是使用一个
私有静态随机变量rando=new Random()在我的课堂上,这个问题已经解决了。新的洗牌方法是:
/// <summary>
/// Shuffles the List.
/// </summary>
/// <typeparam name="T">Type in the list</typeparam>
/// <param name="list">The list.</param>
/// <returns>Shuffled list</returns>
public static List<T> Shuffle<T>(this List<T> list)
{
List<T> randomList = new List<T>();
while (list.Any())
{
var randomIndex = rando.Next(0, list.Count());
randomList.Add(list[randomIndex]); //add it to the new, random list
list.RemoveAt(randomIndex); //remove to avoid duplicates
}
return randomList; //return the new random list
}
//
///洗牌列表。
///
///在列表中键入
///名单。
///无序列表
公共静态列表洗牌(此列表)
{
List randomList=新列表();
while(list.Any())
{
var randomIndex=rando.Next(0,list.Count());
添加(list[randomIndex]);//将其添加到新的随机列表中
list.RemoveAt(randomIndex);//删除以避免重复
}
return randomList;//返回新的随机列表
}
谢谢你的帮助,这让我找到了答案。Random()对象确实每次都给出相同的结果,我通过在类中创建一个私有的static Random()来解决它。这是一个糟糕的Shuffle
函数-它在输入列表中具有破坏性。只需尝试执行return list.OrderBy(x=>rando.Next()).ToList()相反,我了解到OrderBy对于较大的列表效率较低,这是本项目的一部分。你认为这个函数比Orderby更有效吗?还是值得为大型集合销毁输入列表?它比你的方法效率高很多。每次删除一个元素时,都会导致列表移动一半的元素,因此它会执行n*n/2
操作。排序的复杂性通常是n*logn*
。如果您有一个包含1000个元素的列表,那么您的方法的成本将高出50倍。如果你有100000个元素,那么你的要贵3000倍。你应该总是做一些计时来测试。我编写了一个快速测试应用程序,比较这两种方法。对于大约10000个列表,所用的时间是相似的。对于1000个左右的列表,您的方法更快(1.3ms vs 2.3ms-是的,它节省了1ms)。对于100000个大小的列表,我的方法快了10倍。当我将列表设置为1000000个元素时,Shuffle
方法一直在运行,我停止了测试,但是.OrderBy
方法在大约半秒钟内返回了一个结果。@Enigmativity-以及=equal,这可能不是真的。;)我不是说你的代码慢,我提供的链接只是另一个想法。
/// <summary>
/// Shuffles the List.
/// </summary>
/// <typeparam name="T">Type in the list</typeparam>
/// <param name="list">The list.</param>
/// <returns>Shuffled list</returns>
public static List<T> Shuffle<T>(this List<T> list)
{
List<T> randomList = new List<T>();
while (list.Any())
{
var randomIndex = rando.Next(0, list.Count());
randomList.Add(list[randomIndex]); //add it to the new, random list
list.RemoveAt(randomIndex); //remove to avoid duplicates
}
return randomList; //return the new random list
}