-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bump NUnit from 3.14.0 to 4.0.1 (#161)
- Loading branch information
1 parent
c7a37c2
commit a3f2071
Showing
46 changed files
with
13,802 additions
and
13,888 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,81 +1,96 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading; | ||
|
||
namespace BadMedicine | ||
namespace BadMedicine; | ||
|
||
/// <summary> | ||
/// Picks random object of Type T based on a specified probability for each element. | ||
/// </summary> | ||
/// <typeparam name="T"></typeparam> | ||
public sealed class BucketList<T> : IEnumerable<(T item,int probability)> | ||
{ | ||
private Lazy<int> _total; | ||
private readonly List<(T item, int probability)> _list=[]; | ||
|
||
/// <summary> | ||
/// Picks random object of Type T based on a specified probability for each element. | ||
/// Construct an empty BucketList | ||
/// </summary> | ||
/// <typeparam name="T"></typeparam> | ||
public class BucketList<T> | ||
public BucketList() | ||
{ | ||
_total = new Lazy<int>(GetTotal,LazyThreadSafetyMode.ExecutionAndPublication); | ||
} | ||
|
||
readonly List<T> _buckets = new List<T>(); | ||
readonly List<int> _probabilities = new List<int>(); | ||
private int GetTotal() => _list.Sum(static t => t.probability); | ||
|
||
private int? _total = null; | ||
/// <summary> | ||
/// Returns a random bucket (based on the probability of each bucket) | ||
/// </summary> | ||
/// <returns></returns> | ||
public T GetRandom(Random r) | ||
{ | ||
var toPick = r.Next(0, _total.Value); | ||
|
||
/// <summary> | ||
/// Returns a random bucket (based on the probability of each bucket) | ||
/// </summary> | ||
/// <returns></returns> | ||
public T GetRandom(Random r) | ||
for (var i = 0; i < _list.Count; i++) | ||
{ | ||
//cache the total | ||
_total = _total??_probabilities.Sum(); | ||
toPick -= _list[i].probability; | ||
if (toPick < 0) | ||
return _list[i].item; | ||
} | ||
|
||
var toPick = r.Next(0, _total.Value); | ||
throw new Exception("Could not GetRandom"); | ||
} | ||
|
||
for (var i = 0; i < _probabilities.Count; i++) | ||
{ | ||
toPick -= _probabilities[i]; | ||
if (toPick < 0) | ||
return _buckets[i]; | ||
} | ||
|
||
throw new Exception("Could not GetRandom"); | ||
} | ||
/// <summary> | ||
/// Returns a random bucket from the element indices provided (based on the probability of each bucket) | ||
/// </summary> | ||
/// <param name="usingOnlyIndices"></param> | ||
/// <param name="r"></param> | ||
/// <returns></returns> | ||
public T GetRandom(IEnumerable<int> usingOnlyIndices, Random r) | ||
{ | ||
var idx = usingOnlyIndices.ToList(); | ||
|
||
var total = idx.Sum(t => _list[t].probability); | ||
|
||
/// <summary> | ||
/// Returns a random bucket from the element indices provided (based on the probability of each bucket) | ||
/// </summary> | ||
/// <param name="usingOnlyIndices"></param> | ||
/// <param name="r"></param> | ||
/// <returns></returns> | ||
public T GetRandom(IEnumerable<int> usingOnlyIndices, Random r) | ||
{ | ||
var idx = usingOnlyIndices.ToList(); | ||
var toPick = r.Next(0, total); | ||
|
||
var total = idx.Sum(t=>_probabilities[t]); | ||
foreach (var i in idx) | ||
{ | ||
toPick -= _list[i].probability; | ||
if (toPick < 0) | ||
return _list[i].item; | ||
} | ||
|
||
var toPick = r.Next(0, total); | ||
throw new Exception("Could not GetRandom"); | ||
} | ||
|
||
foreach (var i in idx) | ||
{ | ||
toPick -= _probabilities[i]; | ||
if (toPick < 0) | ||
return _buckets[i]; | ||
} | ||
|
||
throw new Exception("Could not GetRandom"); | ||
} | ||
|
||
/// <summary> | ||
/// Adds a new bucket to the list which will be returned using the total <paramref name="probability"/> ratio (relative | ||
/// to the other buckets). | ||
/// </summary> | ||
/// <param name="probability"></param> | ||
/// <param name="toAdd"></param> | ||
public void Add(int probability, T toAdd) | ||
{ | ||
_list.Add((toAdd,probability)); | ||
if (_total.IsValueCreated) | ||
_total = new Lazy<int>(GetTotal, LazyThreadSafetyMode.ExecutionAndPublication); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public IEnumerator<(T item, int probability)> GetEnumerator() | ||
{ | ||
return ((IEnumerable<(T item, int probability)>)_list).GetEnumerator(); | ||
} | ||
|
||
/// <summary> | ||
/// Adds a new bucket to the list which will be returned using the total <paramref name="probability"/> ratio (relative | ||
/// to the other buckets). | ||
/// </summary> | ||
/// <param name="probability"></param> | ||
/// <param name="toAdd"></param> | ||
public void Add(int probability, T toAdd) | ||
{ | ||
_probabilities.Add(probability); | ||
_buckets.Add(toAdd); | ||
_total = null; | ||
} | ||
IEnumerator IEnumerable.GetEnumerator() | ||
{ | ||
return ((IEnumerable)_list).GetEnumerator(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.