2009-08-06 40 views
1

私はalgorithm for collapsing rangesについて私の質問で得た様々な答えをテストできると思っていました。だから私は範囲の全体を作成し、さまざまなメソッドがそれをどのように処理するかを見るメソッドを作成する必要があると思っていた。C#:ランダムに均等に分布したランダムな範囲を作成するためのアルゴリズム

ランダムなものを生成することについては、あまり良くありません。

private static IEnumerable<Range<int>> GenerateRanges() 
    { 
     var r = new Random(); 
     var n = 10000; 
     while(--n >= 0) 
     { 
      var start = r.Next(10000); 
      var end = r.Next(10000); 
      if (end < start) 
       Swap(ref start, ref end); 
      yield return Range.Create(start, end); 
     } 
    } 

これは当然の範囲の多くを作成しますが、私は常にそれらを崩壊した後にのみ、1つの範囲で終わるので、彼らは特に興味深い結果が得られていない:私はこのようなものを作成しました。より興味深い範囲を作成するにはどうすればいいですか?

答えて

1
private static IEnumerable<Range<int>> GenerateRanges(int amount, int max, float density, int seed) 
{ 
    var r = new Random(seed); 
    var commonLength = max * density/amount; // edited 
    var maxLength = commonLength * 2; 
    while(--amount >= 0) 
    { 
     var length = r.Next(maxLength); 
     var start = r.Next(max - length); 
     var end = start + length; 
     yield return Range.Create(start, end); 
    } 
} 

使い方は次のようになります。GenerateRanges(1000, 10000, 1.0, someTestSeed) かが考えられます。GenerateRanges(1000, 10000, .5, someTestSeed)少ない重複

+0

うまくいっているようです。 whileループで '10000'と書かれている' max'と言うべきでしょうか? 10000から100までの最大値を調整しようとしましたが、10000までの数値が得られました。もし私がそれをmaxに変更した場合、予想どおりに動作しているようですが、何が起こっているのか分かりません:p – Svish

+0

'密度が1で、1000の範囲が必要な場合、すべての範囲は0と2の間でなければなりません。intなので、丸めが発生します。密度を上げ、私のコードを更新して、適切なint計算を得るためにそれを編集します。 – Dykam

+0

浮動小数点数が必要なときは、浮動小数点型にmaxの型を変更し、Range <>の型を必ず捨ててください。 – Dykam

0

このように、あなたはまた、コーナーケースのために特定のテストを追加していることを確認してください:範囲

  • 2つの同一の範囲一部重複部分的
  • 二つの範囲をオーバーラップ
  • 二つの範囲の

    • 空のリスト反対の順序で指定してください(つまり、最初にリストに追加する変更)
    • 重複しない2つの範囲と両方の方法を確認してください
    • 接触する2つの範囲(すなわち、 1-10と11-20)は整数ですが、おそらくそれらを組み合わせるべきではありません。

    ランダムテストの問題は、通常、テスト自体で計算を実行するコードを複製する必要があります。そうでなければ、あなたは何に対してテストしようとしていますか?もう一度やり直して比較する以外は、ランダムデータが正しく処理されたことをどのように知っていますか?

  • +0

    これは非常に真実です。そのような場合は、自分で書く方がはるかに良いでしょう。これはパフォーマンスのためのもので、速いものでした。 – Svish

    0

    あなたはこの試みることができる:小さいNさんから

    • 開始 - いくつかの点であなたを与える必要があり、いくつかの非重複領域

    • そのランダムのために固定されたシードを(使用します異なる値に設定することができます)、再現可能な結果を​​得ることができます。

    その他のアイデアは、いくつかのループを使用することです。生成、および分のそれ自身の設定した各ループ - 最大値は:

    var start = r.Next(5000); 
    var end = start + r.Next(1000); 
    
    var start = 6500 + r.Next(1000); 
    var end = start + r.Next(1000); 
    

    これは、常に最後に少なくとも二つの非重複領域(約あなたを与える必要があります。最大0から6000および6500から8500)

    0

    のためにあなたが始点と終点を選択した場合、範囲は均等に分散されることはありません中央に集中している。範囲の50%が中心点と重なります。

    まず、範囲のサイズを選択し、それを下限と上限の間のどこかに配置します。0から10000サイズに:

    private static IEnumerable<Range<int>> GenerateRanges(int minSize, int maxSize) { 
        Random r = new Random(); 
        for (int n = 0; n < 10000; n++) { 
         int size = r.Next(minSize, maxSize); 
         int start = r.Next(10000 - size); 
         yield return Range.Create(start, start + size); 
        } 
    } 
    

    あなたはそれがオーバーラップする範囲を取得する方法を制御する可能性に、minSizeおよびmaxSizeのために異なる値を使用することができます。

    関連する問題