mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-22 04:53:29 +01:00
Added GetRandomEntry and GetRandomWeightedEntry to SingleRandom
This commit is contained in:
parent
2c7ffee427
commit
7e64b8a990
3 changed files with 66 additions and 21 deletions
|
@ -17,6 +17,7 @@ Jump to version:
|
||||||
Additions
|
Additions
|
||||||
- Added GraphicsExtensions.WithRenderTargets, a multi-target version of WithRenderTarget
|
- Added GraphicsExtensions.WithRenderTargets, a multi-target version of WithRenderTarget
|
||||||
- Added Zero, One, Linear and Clamp to Easings
|
- Added Zero, One, Linear and Clamp to Easings
|
||||||
|
- Added GetRandomEntry and GetRandomWeightedEntry to SingleRandom
|
||||||
|
|
||||||
Fixes
|
Fixes
|
||||||
- Fixed TextInput not working correctly when using surrogate pairs
|
- Fixed TextInput not working correctly when using surrogate pairs
|
||||||
|
|
|
@ -16,8 +16,7 @@ namespace MLEM.Extensions {
|
||||||
/// <typeparam name="T">The entries' type</typeparam>
|
/// <typeparam name="T">The entries' type</typeparam>
|
||||||
/// <returns>A random entry</returns>
|
/// <returns>A random entry</returns>
|
||||||
public static T GetRandomEntry<T>(this Random random, ICollection<T> entries) {
|
public static T GetRandomEntry<T>(this Random random, ICollection<T> entries) {
|
||||||
// ElementAt internally optimizes for IList access so we don't have to here
|
return RandomExtensions.GetRandomEntry(entries, random.NextSingle());
|
||||||
return entries.ElementAt(random.Next(entries.Count));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -31,28 +30,12 @@ namespace MLEM.Extensions {
|
||||||
/// <returns>A random entry, based on the entries' weight</returns>
|
/// <returns>A random entry, based on the entries' weight</returns>
|
||||||
/// <exception cref="IndexOutOfRangeException">If the weight function returns different weights for the same entry</exception>
|
/// <exception cref="IndexOutOfRangeException">If the weight function returns different weights for the same entry</exception>
|
||||||
public static T GetRandomWeightedEntry<T>(this Random random, ICollection<T> entries, Func<T, int> weightFunc) {
|
public static T GetRandomWeightedEntry<T>(this Random random, ICollection<T> entries, Func<T, int> weightFunc) {
|
||||||
var totalWeight = entries.Sum(weightFunc);
|
return RandomExtensions.GetRandomWeightedEntry(entries, weightFunc, random.NextSingle());
|
||||||
var goalWeight = random.Next(totalWeight);
|
|
||||||
var currWeight = 0;
|
|
||||||
foreach (var entry in entries) {
|
|
||||||
currWeight += weightFunc(entry);
|
|
||||||
if (currWeight > goalWeight)
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
throw new IndexOutOfRangeException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="GetRandomWeightedEntry{T}(System.Random,System.Collections.Generic.ICollection{T},System.Func{T,int})"/>
|
/// <inheritdoc cref="GetRandomWeightedEntry{T}(System.Random,System.Collections.Generic.ICollection{T},System.Func{T,int})"/>
|
||||||
public static T GetRandomWeightedEntry<T>(this Random random, ICollection<T> entries, Func<T, float> weightFunc) {
|
public static T GetRandomWeightedEntry<T>(this Random random, ICollection<T> entries, Func<T, float> weightFunc) {
|
||||||
var totalWeight = entries.Sum(weightFunc);
|
return RandomExtensions.GetRandomWeightedEntry(entries, weightFunc, random.NextSingle());
|
||||||
var goalWeight = random.NextDouble() * totalWeight;
|
|
||||||
var currWeight = 0F;
|
|
||||||
foreach (var entry in entries) {
|
|
||||||
currWeight += weightFunc(entry);
|
|
||||||
if (currWeight > goalWeight)
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
throw new IndexOutOfRangeException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -87,5 +70,32 @@ namespace MLEM.Extensions {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
internal static T GetRandomEntry<T>(ICollection<T> entries, float randomValue) {
|
||||||
|
// ElementAt internally optimizes for IList access so we don't have to here
|
||||||
|
return entries.ElementAt((int) (randomValue * entries.Count));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static T GetRandomWeightedEntry<T>(ICollection<T> entries, Func<T, int> weightFunc, float randomValue) {
|
||||||
|
var goalWeight = randomValue * entries.Sum(weightFunc);
|
||||||
|
var currWeight = 0;
|
||||||
|
foreach (var entry in entries) {
|
||||||
|
currWeight += weightFunc(entry);
|
||||||
|
if (currWeight > goalWeight)
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
throw new IndexOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static T GetRandomWeightedEntry<T>(ICollection<T> entries, Func<T, float> weightFunc, float randomValue) {
|
||||||
|
var goalWeight = randomValue * entries.Sum(weightFunc);
|
||||||
|
var currWeight = 0F;
|
||||||
|
foreach (var entry in entries) {
|
||||||
|
currWeight += weightFunc(entry);
|
||||||
|
if (currWeight > goalWeight)
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
throw new IndexOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
namespace MLEM.Misc {
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MLEM.Extensions;
|
||||||
|
|
||||||
|
namespace MLEM.Misc {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The SingleRandom class allows generating single, one-off pseudorandom numbers based on a seed or a <see cref="SeedSource"/>.
|
/// The SingleRandom class allows generating single, one-off pseudorandom numbers based on a seed or a <see cref="SeedSource"/>.
|
||||||
/// The types of numbers that can be generated are <see cref="int"/> and <see cref="float"/>, both of which can be generated with specific minimum and maximum values if desired.
|
/// The types of numbers that can be generated are <see cref="int"/> and <see cref="float"/>, both of which can be generated with specific minimum and maximum values if desired.
|
||||||
|
@ -138,5 +142,35 @@
|
||||||
return (maxValue - minValue) * SingleRandom.Single(source) + minValue;
|
return (maxValue - minValue) * SingleRandom.Single(source) + minValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a random entry from the given collection with uniform chance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entries">The entries to choose from</param>
|
||||||
|
/// <param name="source">The <see cref="SeedSource"/> to use.</param>
|
||||||
|
/// <typeparam name="T">The entries' type</typeparam>
|
||||||
|
/// <returns>A random entry</returns>
|
||||||
|
public static T GetRandomEntry<T>(ICollection<T> entries, SeedSource source) {
|
||||||
|
return RandomExtensions.GetRandomEntry(entries, SingleRandom.Single(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a random entry from the given collection based on the specified weight function.
|
||||||
|
/// A higher weight for an entry increases its likeliness of being picked.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entries">The entries to choose from</param>
|
||||||
|
/// <param name="weightFunc">A function that applies weight to each entry</param>
|
||||||
|
/// <param name="source">The <see cref="SeedSource"/> to use.</param>
|
||||||
|
/// <typeparam name="T">The entries' type</typeparam>
|
||||||
|
/// <returns>A random entry, based on the entries' weight</returns>
|
||||||
|
/// <exception cref="IndexOutOfRangeException">If the weight function returns different weights for the same entry</exception>
|
||||||
|
public static T GetRandomWeightedEntry<T>(ICollection<T> entries, Func<T, int> weightFunc, SeedSource source) {
|
||||||
|
return RandomExtensions.GetRandomWeightedEntry(entries, weightFunc, SingleRandom.Single(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="GetRandomWeightedEntry{T}(System.Collections.Generic.ICollection{T},System.Func{T,int},MLEM.Misc.SeedSource)"/>
|
||||||
|
public static T GetRandomWeightedEntry<T>(ICollection<T> entries, Func<T, float> weightFunc, SeedSource source) {
|
||||||
|
return RandomExtensions.GetRandomWeightedEntry(entries, weightFunc, SingleRandom.Single(source));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue