0

要素の追加中に入力された重みに基づいてランダムな値を返す Container クラスを作成するにはどうすればよいでしょうか?

理想的には、次のように使用できるはずです。

var randomContainer = new RandomContainer<IThing>();
randomContainer.Add(new CoolThing(), 80);
randomContainer.Add(new AwesomeThing(), 20);
IThing thing = randomContainer.Get();

つまり、80% の確率で CoolThing になり、20% の確率で AwesomeThing になります。

ただし、アルゴリズムでは、重みの合計が 100 になる必要はないため、これも可能である必要があります。

var randomContainer = new RandomContainer<IThing>();
randomContainer.Add(new CoolThing(), 398);
randomContainer.Add(new AwesomeThing(), 485);
randomContainer.Add(new SpecialThing(), 1);
IThing thing = randomContainer.Get();

そのようなアルゴリズムを実装する方法はありますか? クラスに必要なメンバー/プロパティは何ですか? ICollection を実装する意味はありますか?

4

2 に答える 2

1

ダニエル・ヒルガースの答えは正しいとマークしています。彼は私を正しい軌道に乗せたからです。

実装例が必要な場合:

public class RandomContainer<T> 
{
    private Random _random = new Random();

    private Dictionary<T, int> _objects = new Dictionary<T, int>();
    private int _weightSum;

    public RandomContainer()
    {           
    }

    public void Add(T obj, int weight)
    {          
        _objects.Add(obj, weight);
        _weightSum += weight;
    }

    public T Get()
    {
        int sumExtra = 0;
        int rand = _random.Next(0, _weightSum);
        foreach(var kvp in _objects)
        {
            if(rand < kvp.Value + sumExtra)
                return kvp.Key;
            sumExtra += kvp.Value;
        }
        return default(T); // This shouldn't be reached
    }
}

多くの標準的なメソッドが含まれているわけではありませんが、いずれにせよ重要なのは Get() 関数にあり、残りは簡単に実装できるはずです。

于 2013-02-14T14:21:48.380 に答える
1

そのアルゴリズムは非常に単純なはずです。

1 からすべての重みの合計までのランダムな値を選択します。値は、返すオブジェクトを示します。

2 番目のサンプルの例:

  • 1 ~ 398 の値が返されCoolThingます。
  • 値 399 から 883 (= 398 + 485) が返されますAwesomeThing
  • 値 884 が返されますSpecialThing
于 2013-02-14T12:53:25.493 に答える