Tidied up ProbabilityObjectArray
This commit is contained in:
@@ -471,7 +471,7 @@ public class InsuranceController(
|
||||
var countOfAttachmentsToRemove = GetAttachmentCountToRemove(weightedAttachmentByPrice, traderId);
|
||||
|
||||
// Create prob array and add all attachments with rouble price as the weight
|
||||
var attachmentsProbabilityArray = new ProbabilityObjectArray<ProbabilityObject<string, double?>, string, double?>(_mathUtil, _cloner, []);
|
||||
var attachmentsProbabilityArray = new ProbabilityObjectArray<ProbabilityObject<string, double?>, string, double?>(_mathUtil, _cloner);
|
||||
foreach (var attachmentTpl in weightedAttachmentByPrice)
|
||||
{
|
||||
attachmentsProbabilityArray.Add(
|
||||
|
||||
@@ -307,7 +307,7 @@ public class LocationLootGenerator(
|
||||
|
||||
// Create probability array with all possible container ids in this group and their relative probability of spawning
|
||||
var containerDistribution =
|
||||
new ProbabilityObjectArray<ProbabilityObject<string, double>, string, double>(_mathUtil, _cloner, []);
|
||||
new ProbabilityObjectArray<ProbabilityObject<string, double>, string, double>(_mathUtil, _cloner);
|
||||
foreach (var x in containerIds)
|
||||
{
|
||||
var value = containerData.ContainerIdsWithProbability[x];
|
||||
@@ -556,7 +556,7 @@ public class LocationLootGenerator(
|
||||
{
|
||||
// Create probability array to calcualte the total count of lootable items inside container
|
||||
var itemCountArray =
|
||||
new ProbabilityObjectArray<ProbabilityObject<int, float?>, int, float?>(_mathUtil, _cloner, []);
|
||||
new ProbabilityObjectArray<ProbabilityObject<int, float?>, int, float?>(_mathUtil, _cloner);
|
||||
var countDistribution = staticLootDist[containerTypeId]?.ItemCountDistribution;
|
||||
if (countDistribution is null)
|
||||
{
|
||||
@@ -600,7 +600,7 @@ public class LocationLootGenerator(
|
||||
var seasonalItemTplBlacklist = _seasonalEventService.GetInactiveSeasonalEventItems();
|
||||
|
||||
var itemDistribution =
|
||||
new ProbabilityObjectArray<ProbabilityObject<string, float?>, string, float?>(_mathUtil, _cloner, []);
|
||||
new ProbabilityObjectArray<ProbabilityObject<string, float?>, string, float?>(_mathUtil, _cloner);
|
||||
|
||||
var itemContainerDistribution = staticLootDist[containerTypeId]?.ItemDistribution;
|
||||
if (itemContainerDistribution is null)
|
||||
|
||||
@@ -1,111 +1,119 @@
|
||||
using Core.Utils.Cloners;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
|
||||
namespace Core.Utils.Collections;
|
||||
|
||||
/**
|
||||
* Array of ProbabilityObjectArray which allow to randomly draw of the contained objects
|
||||
* based on the relative probability of each of its elements.
|
||||
* The probabilities of the contained element is not required to be normalized.
|
||||
*
|
||||
* Example:
|
||||
* po = new ProbabilityObjectArray(
|
||||
* new ProbabilityObject("a", 5),
|
||||
* new ProbabilityObject("b", 1),
|
||||
* new ProbabilityObject("c", 1)
|
||||
* );
|
||||
* res = po.draw(10000);
|
||||
* // count the elements which should be distributed according to the relative probabilities
|
||||
* res.filter(x => x==="b").reduce((sum, x) => sum + 1 , 0)
|
||||
*/
|
||||
public class ProbabilityObjectArray<T, K, V> : List<T> where T : ProbabilityObject<K,V>
|
||||
/// <summary>
|
||||
/// Array of ProbabilityObjectArray which allow to randomly draw of the contained objects
|
||||
/// based on the relative probability of each of its elements.
|
||||
/// The probabilities of the contained element is not required to be normalized.
|
||||
///
|
||||
/// Example:
|
||||
/// po = new ProbabilityObjectArray(
|
||||
/// new ProbabilityObject("a", 5),
|
||||
/// new ProbabilityObject("b", 1),
|
||||
/// new ProbabilityObject("c", 1)
|
||||
/// );
|
||||
/// res = po.draw(10000);
|
||||
/// // count the elements which should be distributed according to the relative probabilities
|
||||
/// res.filter(x => x==="b").reduce((sum, x) => sum + 1 , 0)
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="K"></typeparam>
|
||||
/// <typeparam name="V"></typeparam>
|
||||
public class ProbabilityObjectArray<T, K, V> : List<T> where T : ProbabilityObject<K, V>
|
||||
{
|
||||
private MathUtil _mathUtil;
|
||||
private ICloner _cloner;
|
||||
private readonly MathUtil _mathUtil;
|
||||
private readonly ICloner _cloner;
|
||||
|
||||
public ProbabilityObjectArray(
|
||||
MathUtil mathUtil,
|
||||
ICloner cloner,
|
||||
ICollection<T> items
|
||||
) : base(items)
|
||||
ICollection<T>? items = null
|
||||
) : base(items ?? [])
|
||||
{
|
||||
_mathUtil = mathUtil;
|
||||
_cloner = cloner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the normalized cumulative probability of the ProbabilityObjectArray's elements normalized to 1
|
||||
* @param {array} probValues The relative probability values of which to calculate the normalized cumulative sum
|
||||
* @returns {array} Cumulative Sum normalized to 1
|
||||
*/
|
||||
/// <summary>
|
||||
/// Calculates the normalized cumulative probability of the ProbabilityObjectArray's elements normalized to 1
|
||||
/// </summary>
|
||||
/// <param name="probValues">The relative probability values of which to calculate the normalized cumulative sum</param>
|
||||
/// <returns>Cumulative Sum normalized to 1</returns>
|
||||
public List<double> CumulativeProbability(List<double> probValues)
|
||||
{
|
||||
var sum = _mathUtil.ListSum(probValues);
|
||||
var probCumsum = _mathUtil.ListCumSum(probValues);
|
||||
probCumsum = _mathUtil.ListProduct(probCumsum, 1D / sum);
|
||||
|
||||
return probCumsum;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter What is inside ProbabilityObjectArray
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// <returns>Filtered results</returns>
|
||||
public ProbabilityObjectArray<T, K, V> Filter(Predicate<ProbabilityObject<K, V>> predicate)
|
||||
{
|
||||
var filtered = new ProbabilityObjectArray<T, K, V>(_mathUtil, _cloner, new List<T>());
|
||||
var result = new ProbabilityObjectArray<T, K, V>(_mathUtil, _cloner, new List<T>());
|
||||
foreach (var probabilityObject in this)
|
||||
{
|
||||
if (predicate.Invoke(probabilityObject))
|
||||
filtered.Add(probabilityObject);
|
||||
}
|
||||
return filtered;
|
||||
{
|
||||
result.Add(probabilityObject);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone this ProbabilitObjectArray
|
||||
* @returns {ProbabilityObjectArray} Deep Copy of this ProbabilityObjectArray
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Deep clone this ProbabilityObjectArray
|
||||
/// </summary>
|
||||
/// <returns>Deep Copy of ProbabilityObjectArray</returns>
|
||||
public ProbabilityObjectArray<T, K, V> Clone()
|
||||
{
|
||||
var clone = _cloner.Clone(this);
|
||||
var probabliltyObjects = new ProbabilityObjectArray<T, K, V>(
|
||||
var probabilityObjects = new ProbabilityObjectArray<T, K, V>(
|
||||
_mathUtil,
|
||||
_cloner,
|
||||
new List<T>()
|
||||
);
|
||||
probabliltyObjects.AddRange(clone);
|
||||
return probabliltyObjects;
|
||||
probabilityObjects.AddRange(clone);
|
||||
|
||||
return probabilityObjects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop an element from the ProbabilityObjectArray
|
||||
*
|
||||
* @param {string} key The key of the element to drop
|
||||
* @returns {ProbabilityObjectArray} ProbabilityObjectArray without the dropped element
|
||||
*/
|
||||
/// <summary>
|
||||
/// Drop an element from the ProbabilityObjectArray
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the element to drop</param>
|
||||
/// <returns>ProbabilityObjectArray without the dropped element</returns>
|
||||
public ProbabilityObjectArray<T, K, V> Drop(K key)
|
||||
{
|
||||
return (ProbabilityObjectArray<T, K, V>)this.Where((r) => !r.Key?.Equals(key) ?? false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the data field of a element of the ProbabilityObjectArray
|
||||
* @param {string} key The key of the element whose data shall be retrieved
|
||||
* @returns {object} The data object
|
||||
*/
|
||||
/// <summary>
|
||||
/// Return the data field of an element of the ProbabilityObjectArray
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the element whose data shall be retrieved</param>
|
||||
/// <returns>Stored data object</returns>
|
||||
public V? Data(K key)
|
||||
{
|
||||
var element = this.FirstOrDefault(r => r.Key?.Equals(key) ?? false);
|
||||
return element == null ? default : element.Data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the relative probability of an element by its key
|
||||
*
|
||||
* Example:
|
||||
* po = new ProbabilityObjectArray(new ProbabilityObject("a", 5), new ProbabilityObject("b", 1))
|
||||
* po.maxProbability() // returns 5
|
||||
*
|
||||
* @param {string} key The key of the element whose relative probability shall be retrieved
|
||||
* @return {number} The relative probability
|
||||
*/
|
||||
/// <summary>
|
||||
/// Get the relative probability of an element by its key
|
||||
///
|
||||
/// Example:
|
||||
/// po = new ProbabilityObjectArray(new ProbabilityObject("a", 5), new ProbabilityObject("b", 1))
|
||||
/// po.maxProbability() // returns 5
|
||||
/// </summary>
|
||||
/// <param name="key">Key of element whose relative probability shall be retrieved</param>
|
||||
/// <returns>The relative probability</returns>
|
||||
public double? Probability(K key)
|
||||
{
|
||||
var element = this.FirstOrDefault(r => r.Key.Equals(key));
|
||||
@@ -123,21 +131,19 @@ public class ProbabilityObjectArray<T, K, V> : List<T> where T : ProbabilityObje
|
||||
*/
|
||||
public double MaxProbability()
|
||||
{
|
||||
return this.Select(x => x.RelativeProbability).Max();
|
||||
return this.Max(x => x.RelativeProbability).Value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum relative probability out of a ProbabilityObjectArray
|
||||
*
|
||||
* Example:
|
||||
* po = new ProbabilityObjectArray(new ProbabilityObject("a", 5), new ProbabilityObject("b", 1))
|
||||
* po.minProbability() // returns 1
|
||||
*
|
||||
* @return {number} the minimum value of all relative probabilities in this ProbabilityObjectArray
|
||||
*/
|
||||
/// <summary>
|
||||
/// Get the minimum relative probability out of a ProbabilityObjectArray
|
||||
/// * Example:
|
||||
/// po = new ProbabilityObjectArray(new ProbabilityObject("a", 5), new ProbabilityObject("b", 1))
|
||||
/// po.minProbability() // returns 1
|
||||
/// </summary>
|
||||
/// <returns>the minimum value of all relative probabilities in this ProbabilityObjectArray</returns>
|
||||
public double MinProbability()
|
||||
{
|
||||
return this.Select(x => x.RelativeProbability).Min();
|
||||
return this.Min(x => x.RelativeProbability.Value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,7 +166,7 @@ public class ProbabilityObjectArray<T, K, V> : List<T> where T : ProbabilityObje
|
||||
new { probArray = new List<double>(), keyArray = new List<K>() },
|
||||
(acc, x) =>
|
||||
{
|
||||
acc.probArray.Add(x.RelativeProbability);
|
||||
acc.probArray.Add(x.RelativeProbability.Value);
|
||||
acc.keyArray.Add(x.Key);
|
||||
return acc;
|
||||
}
|
||||
@@ -200,34 +206,40 @@ public class ProbabilityObjectArray<T, K, V> : List<T> where T : ProbabilityObje
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A ProbabilityObject which is use as an element to the ProbabilityObjectArray array
|
||||
* It contains a key, the relative probability as well as optional data.
|
||||
*/
|
||||
/// <summary>
|
||||
/// A ProbabilityObject which is use as an element to the ProbabilityObjectArray array
|
||||
/// It contains a key, the relative probability as well as optional data.
|
||||
/// </summary>
|
||||
/// <typeparam name="K"></typeparam>
|
||||
/// <typeparam name="V"></typeparam>
|
||||
public class ProbabilityObject<K, V>
|
||||
{
|
||||
public ProbabilityObject()
|
||||
{ }
|
||||
|
||||
[JsonPropertyName("key")]
|
||||
public K Key { get; set; }
|
||||
|
||||
[JsonPropertyName("relativeProbability")]
|
||||
public double RelativeProbability { get; set; }
|
||||
|
||||
[JsonPropertyName("data")]
|
||||
public V? Data { get; set; }
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* varructor for the ProbabilityObject
|
||||
* @param {string} key The key of the element
|
||||
* @param {number} relativeProbability The relative probability of this element
|
||||
* @param {any} data Optional data attached to the element
|
||||
*/
|
||||
public ProbabilityObject(K key, double relativeProbability, V? data)
|
||||
* constructor for the ProbabilityObject
|
||||
* @param {string} key The key of the element
|
||||
* @param {number} relativeProbability The relative probability of this element
|
||||
* @param {any} data Optional data attached to the element
|
||||
*/
|
||||
public ProbabilityObject(K key, double? relativeProbability, V? data)
|
||||
{
|
||||
Key = key;
|
||||
RelativeProbability = relativeProbability;
|
||||
Data = data;
|
||||
}
|
||||
|
||||
[JsonPropertyName("key")]
|
||||
public K? Key { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Weighting of key compared to other ProbabilityObjects
|
||||
/// </summary>
|
||||
[JsonPropertyName("relativeProbability")]
|
||||
public double? RelativeProbability { get; set; }
|
||||
|
||||
[JsonPropertyName("data")]
|
||||
public V? Data { get; set; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user