2017-09-28 12 views
1

我目前遇到了一个问题,我尝试生成一个随机旅游对象(Traveling Salesman)的列表。当我通过代码进行调试时,一切正常,但是当我运行代码(或者甚至运行这段代码)时,我的列表中充满了所有相同的对象。C#List对象在不调试时被重用

for (int i = 0; i < populationSize; i++) 
{ 
    var newTour = new Tour(distanceCalculator); 
    newTour.GenerateIndividual(); 
    this.Tours[i] = newTour; 
    newTour = null; 
} 

GenerateIndividual方法是Tour物体填满了城市旅游的一个方法,然后随机化它:

public void GenerateIndividual() 
{ 
     Path = new List<Location>(new Location[GenericGraph.NumberOfLocations()]); 

     // Loop through all our destination cities and add them to our tour 
     for (int cityIndex = 0; cityIndex < GenericGraph.NumberOfLocations(); cityIndex++) 
     { 
      SetLocation(cityIndex, GenericGraph.LocationList[cityIndex]); 
     } 

     // Randomly reorder the tour 
     Path = Path.Shuffle().ToList(); 
    } 

我所知道的洗牌正在因为路径总是以随机顺序。问题是只有当我调试到for循环时,路径中的Tour才会更新。例如,如果我的populationSize是10,并且我调试了5次,我将会有一个随机5个游览的人口,然后最后的5个游览将与我调试过的最后一个相同。这里发生了什么? newTour对象只在我调试时才被重置,但是当我运行C#时一遍又一遍地使用同一个对象?

回答

1

然后最后5次巡视将会与上次我调试过一样”似乎指向Shuffle方法不起作用。

我的猜测是Shuffle方法调用new Random()每次它被调用,因为这段代码非常短,它每次都会产生相同的结果。在调试你放慢速度,Shuffle似乎工作正常,我不认为这是事实。

(奇怪的是,为什么最后5个和第5个元素相同,我不确定那里发生了什么)。

+0

谢谢你的帮助,这导致我的答案。 Random()对象每次都会得到相同的结果,我通过在类中创建一个私有静态Random()来解决它。 –

0

问题确实在我的Shuffle方法中。正如@mayu指出的那样,我使用了一个新的Random对象,每次调用使用相同的种子,每次都给我相同的随机数。通过在我的班级中改用private static Random rando = new Random();,问题得以解决。新Shuffle方法是:

/// <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 
    } 
+0

这是一个糟糕的'shuffle'函数 - 它对输入列表具有破坏性。试试'return list.OrderBy(x => rando.Next())。ToList();'而不是。 – Enigmativity

+0

我读过OrderBy对较大的列表来说效率较低,这是该项目的一部分。你认为这个函数比Orderby更有效吗?还是值得销毁大集合的输入列表? –

+0

它比你的方法更有效率很多。你每次移除一个元素都会导致你的列表移动一半元素 - 所以它正在执行“n * n/2”操作。排序通常是复杂性中的“n * log n *”。如果你有一个包含1,000个元素的列表,那么你的方法花费高出50倍。如果你有100,000个元素,那么你的成本就要高出3000倍。 – Enigmativity

相关问题