0
我正在實現一個擴展方法,返回TKey
和IDictionary<TKey, TValue>
作爲參數。如果TValue
是double
,該方法很可能返回具有最高值的TKey
。否則,它會隨機返回一個TKey
。Linq重載where子句排除特定類型
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>
始終即使有TValue
double
調用。任何方式,我可以指定類型TValue
排除雙where子句?即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));
如果我運行這個代碼(取出調用'Normalize',這裏沒有顯示)我得到了'double'和'char'的期望分佈。也許你的'Normalize'方法壞了? – Rawling
@Rawling對不起,這只是一個適用於cateogrical發佈的規範化方法。我添加了它。 –