2017-09-28 3 views
1

現在、私はランダムなTourオブジェクト(Traveling Salesman)のリストを生成しようとしています。私はコードをデバッグすると、すべて正常に動作しますが、コードを実行する(またはコードのこのセクションを実行するだけでも)私のリストはすべて同じオブジェクトでいっぱいです。デバッグしていないときにリストオブジェクトが再利用される

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(); 
    } 

パスがランダムな順序で常にあるので、私はシャッフルが働いている知っています。問題はPath for the Tourがforループにデバッグする場合にのみ更新されることです。たとえば、私のpopulationSizeが10で、5回にわたってデバッグした場合、5つの無作為化されたツアーを持つ人口があります。最後の5回のツアーは、最後にデバッグしたものと同じになります。ここで何が起きてるの? newTourオブジェクトはデバッグ時にのみリセットされますが、C#を実行すると同じオブジェクトを何度も何度も使用していますか?

答えて

1

"最後のツアーは、最後にデバッグしたと同じになります。"シャッフルメソッドが機能していないと思われるようです。

Shuffleのメソッドは、呼び出すたびにnew Random()というメソッドが呼び出され、このコードが非常に短いため毎回同じ結果が生成されるためです。デバッグでは物事が遅くなり、Shuffleはうまくいくように見えますが、私はそうは思わない。

(興味のあることは、最後の5つが第5番目の要素と同じで、そこに何が起こっているのかわかりません)。

+0

ありがとうございました。これが私に答えました。 Random()オブジェクトは毎回同じ結果を返していましたが、クラス内にプライベートな静的Random()を作成して解決しました。 –

0

問題は実際に私のシャッフル方法でした。 @mayuが指摘しているように、私は毎回同じ乱数を与えて同じ種を使っていた新しいRandomオブジェクトを使っていました。私のクラスにprivate static Random 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 
    } 
+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

関連する問題