Skip to content

Input Normalizations

Since an input can vary widely in value, so we need a tool to normalize it into a fixed range [0,1]. This is where input normalizations come into play. This step is crucial because it ensures that decisions are scored on a consistent scale, allowing us to compare their scores and select the highest-scoring decision.

Creating Input Normalizations

To create a new input normalization, define a new class that inherits from InputNormalization<TValue> and override the OnCalculateNormalizedInput method. For example:

[Category("Range")]
public class IsInRangeNormalizationFloat : InRangeNormalization<float>
{
    protected override float OnCalculateNormalizedInput(float rawInput, in InputNormalizationContext context)
    {
        float normalizedInput = rawInput >= MinValue && rawInput <= MaxValue ? 1.0f : 0.0f;
        return normalizedInput;
    }
}

To add the input normalization to the intelligence asset, go to the Input Normalization Tab, select the input normalization type, give it a name, and then click the Create button:
Attachments/UtilityIntelligence/Documentation/UtilityIntelligence/EditorWindow/input-normalization-tab.png

To attach an input normalization to a consideration, select the consideration in the Consideration Tab, and then choose the input normalization’s name from the dropdown menu:

center|600

Note

Note: Input normalizations can only accept inputs with the same value type.

Supported Value Types

Currently, only the supported value types can be adjusted using the Utility Intelligence Editor. Additionally, inputs can only be attached to input normalizations if they share the same value type. Therefore, you should use these types to enable the Status Preview feature to preview which decision is chosen by modifying the input values in the Intelligence Editor. However, you can still use other types if you don’t need this feature.

Adding Parameter Fields

There are many cases when you need to add parameters to an input normalization to customize how it normalizes its input value. To achieve this, you need to declare these parameters as public fields in your input normalizations. Here are some examples of how to do this:

public class IsInCooldownNormalization : InputNormalization<float>
{
    public VariableReference<float> CooldownDuration;

    protected override float OnCalculateNormalizedInput(float rawInput, in InputNormalizationContext context)
    {
        if (rawInput <= CooldownDuration)
            return 1.0f;
        else 
            return 0.0f;
    }
}
public abstract class InRangeNormalization<TValue> : InputNormalization<TValue>
{
    public VariableReference<TValue> MinValue;
    public VariableReference<TValue> MaxValue;
}

[Category("Range")]
public class InRangeNormalizationFloat : InRangeNormalization<float>
{
    protected override float OnCalculateNormalizedInput(float rawInput, in InputNormalizationContext context)
    {
        var diff = MaxValue - MinValue;
        if (diff <= 0.0f) return 0.0f;

        float normalizedInput = (rawInput - MinValue) / (diff);
        return normalizedInput;
    }
}

[Category("Range")]
public class InRangeNormalizationInt : InRangeNormalization<int>
{
    protected override float OnCalculateNormalizedInput(int rawInput, in InputNormalizationContext context)
    {
        var diff = MaxValue - MinValue;
        if (diff <= 0) return 0.0f;

        float normalizedInput = (float)(rawInput - MinValue) / (diff);
        return normalizedInput;
    }
}

Supported Parameter Types

Currently, only the supported field types can be serialized to JSON and adjusted using the Utility Intelligence Editor. Therefore, you should use these types when declaring parameter fields for your input normalizations.

Built-in Input Normalizations

We provides a lot of built-in input normalizations to help you normalize your inputs without having to write a single line of code:

  • Float
    • BasicNormalizationFloat: Clamps the input value into [0, 1]
    • DivideByMaxValueFloat: Divides the input by MaxValue.
    • GreaterThanOrEqualToValueFloat: Returns 1 if the input value is greater than Value; otherwise, returns 0.
    • LessThanOrEqualToValueFloat: Returns 1 if the input value is less than the Value; otherwise, returns 0.
    • InRangeFloat: Maps the input value from [MinValue, MaxValue] to [0, 1]. Note that if the input value is above MaxValue, then the normalized value is 1, and if the input value is below MaxValue, then the normalized value is 0.
    • IsInRangeFloat: Returns 1 if the input value is in the range [MinValue, MaValue]; otherwise, returns 0.
    • IsInCooldownNormalization: Returns 1 if the input (CooldownElapsedTimeInput) is within the cooldown duration; otherwise, returns 0.
  • Int
    • Similar to the floats
  • Bool
    • BasicNormalizationBool: Returns 1 if the input value is true; otherwise, returns 0.

If you like Utility Intelligence, please consider supporting it by leaving a 5-star review on the Asset Store. Your positive feedback motivates me to keep improving and delivering more updates for this framework.
Thank you so much for your support. I love you all! 🥰


Last update : October 17, 2024
Created : September 16, 2024