0

TKeyIDictionary<TKey, TValue>引数として返す拡張メソッドを実装しています。TValueがの場合、メソッドは最大値のdoubleを返す可能性があります。TKeyそれ以外の場合は、ランダムに を返しますTKey

    public static TKey Sample<TKey>(this IDictionary<TKey, double> probabilityTable, Random r)
    {
        probabilityTable.Normalize();

        var roll = r.NextDouble();
        var temp = 0.0;
        foreach (var key in probabilityTable.Keys)
        {
            temp += probabilityTable[key];
            if (roll <= temp)
                return key;
        }

        return default(TKey);
    }

    public static TKey Sample<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, Random r)
    {
        return dictionary.Skip(r.Next(dictionary.Count)).FirstOrDefault().Key;
    }

    public static IDictionary<TKey, double> Normalize<TKey>(this IDictionary<TKey, double> probabilityTable)
    {
        if (probabilityTable.Any(x => x.Value < 0))
            throw new ArgumentOutOfRangeException("probabilityTable", "Probability is expected to be positive.");

        var sum = probabilityTable.Sum(x => x.Value);

        if (Math.Abs(sum - 1) > 1e-8)
            return probabilityTable.ToDictionary(x => x.Key, x => x.Value / sum);

        if (Math.Abs(sum) < 1e-8)
            return probabilityTable.ToDictionary(x => x.Key, x => 1.0 / probabilityTable.Count);

        return probabilityTable;
    }

問題は、Sample<TKey, TValue>常に of でも呼び出されることdoubleですTValueTValuewhere句でexclude double型を指定できる方法はありますか? すなわちwhere TValue: !double

拡張機能を呼び出すコードは次のとおりです。

        var r = new Random();
        var pt = new Dictionary<char, double> {{'A', 0.1}, {'B', 0.2}, {'C', 0.7}};
        var ct = new Dictionary<char, char> {{'A', 'D'}, {'B','E'}, {'C', 'F'}};
        Console.WriteLine(pt.Sample(r)); // expected to return 'C' mostly but uniformly returns key
        Console.WriteLine(ct.Sample(r));
4

1 に答える 1

0

制約は署名の一部ではありません。おそらく次のリンクが役立ちます。

http://blogs.msdn.com/b/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx

于 2012-10-01T15:59:35.090 に答える