【问题标题】:Hash function for arrays of floats and ints in .NET.NET 中浮点数和整数数组的哈希函数
【发布时间】:2021-12-20 04:57:14
【问题描述】:

我有一个特殊的用例,我想将几​​个floatint 的数组散列在一起。我正在编写一个模拟,我想记住一个函数调用。该函数将Settings 类型作为输入。

CapacitiesMaxRates 数组中的值是 64 位浮点数,限制在 0.0 到 1,000,000.0 的范围内。 CapacitiesMaxRates 的长度也限制在 0 到 100。ValveState 是一个 int,其值从 0 到 10。

我知道散列任意浮点数是一个坏主意。在这个特定的用例中,尽管Settings 中的值将是精确的,但逐位匹配到先前的值组合。这就是我想使用Dictionary<Settings, 'Result> 来记忆函数调用的原因。

我要记忆的函数调用很昂贵,并且占用了 >90% 的运行时间。 Settings 中的值组合经常重复并且完全匹配。在模拟期间实际上没有对这些值进行任何数学运算,因此不会发生舍入误差。早期测试表明,记忆这个函数可以使速度提高 10 倍,而不会损失准确性。

我在 F# 中工作,但 .NET 中的任何内容都是可以接受的,因为我可以翻译它。这是 F# 记录的示例。

type Settings = {
    Capacities : array<float>
    MaxRates : array<float>
    ValveState : array<int>
} with
    override this.GetHashCode () = 
        // Your awesome suggestion here

【问题讨论】:

  • CRC32 可能吗? AFAIK 没有用于 CRC32 的内置 HashAlgorithm,但您肯定可以找到一个实现。

标签: .net dictionary hash


【解决方案1】:

您可以使用HashCode.Combine(在 netstandard 2.1 中可用)来组合所有三个数组中所有值的哈希值。

open System

let hashArray (arr : 'T array) =
    let mutable hash = 0
    for x in arr do
        hash <- HashCode.Combine(hash, x)
    hash

[<CustomEquality; NoComparison>]
type Settings = {
    Capacities : array<float>
    MaxRates : array<float>
    ValveState : array<int>
} with
    override this.GetHashCode () =
        HashCode.Combine(
            hashArray this.Capacities,
            hashArray this.MaxRates,
            hashArray this.ValveState
        )

    override this.Equals(o : obj) =
        match o with
        | :? Settings as s ->
            this.Capacities = s.Capacities &&
            this.MaxRates = s.MaxRates &&
            this.ValveState = s.ValveState
        | _ ->
            false

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-22
    • 1970-01-01
    • 2013-05-02
    相关资源
    最近更新 更多