我有一个名为"GetValue()"的方法,它应该在每次方法调用时返回值"A","B","C"或"D".
我希望这个方法在30%的方法调用中返回值"A",在14%的方法调用中返回值"B",值"C"31%..依此类推......
这是顺利分配theese值的最佳方式,我不希望该方法连续返回值"A"xxx次,因为值"A"是它所请求的结果百分比最重要的.
请各位回复者表示赞赏.
您可以使用Random类来实现此目的:
private static Random Generator = new Random();
public string GetValue()
{
var next = Generator.Next(100);
if (next < 30) return "A";
if (next < 44) return "B";
if (next < 75) return "C";
return "D";
}
Run Code Online (Sandbox Code Playgroud)
更新
对于更通用的随机加权值存储,以下可能是一个很好的起点:
public class WeightedValueStore<T> : IDisposable
{
private static readonly Random Generator = new Random();
private readonly List<Tuple<int, T>> _values = new List<Tuple<int, T>>();
private readonly ReaderWriterLockSlim _valueLock = new ReaderWriterLockSlim();
public void AddValue(int weight, T value)
{
_valueLock.EnterWriteLock();
try
{
_values.Add(Tuple.Create(weight, value));
}
finally
{
_valueLock.ExitWriteLock();
}
}
public T GetValue()
{
_valueLock.EnterReadLock();
try
{
var totalWeight = _values.Sum(t => t.Item1);
var next = Random.Next(totalWeight);
foreach (var tuple in _values)
{
next -= tuple.Item1;
if (next < 0) return tuple.Item2;
}
return default(T); // Or throw exception here - only reachable if _values has no elements.
}
finally
{
_valueLock.ExitReadLock();
}
}
public void Dispose()
{
_valueLock.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
哪个可以这样使用:
public string GetValue()
{
using (var valueStore = new WeightedValueStore<string>())
{
valueStore.AddValue(30, "A");
valueStore.AddValue(14, "B");
valueStore.AddValue(31, "C");
valueStore.AddValue(25, "D");
return valueStore.GetValue();
}
}
Run Code Online (Sandbox Code Playgroud)