C# 通过散列来改进集合比较(太聪明了……)

C# 通过散列来改进集合比较(太聪明了……),c#,optimization,hash,C#,Optimization,Hash,在我最后一次尝试提问失败后,这次我尝试了一个更精确的问题: 我所拥有的: ISet的巨大数据集(有限,但我以前浪费了数天的多核处理时间来计算它…) 0到2n之间的输入值列表,n≤十七, 我需要的是: 3) [1],[2]的表,其中我将[2]的每个值映射为[1]的值 处理过程: 对于这个计算,我有一个公式,它接受一个位值(来自[2])和一组位置(来自[1]),并创建一个新的ISet。我需要找出原始集合中的哪一个与结果集合相等(即表中“A7”处的“单元格”可能指向“B”) 天真的方式: 计算新的IS

在我最后一次尝试提问失败后,这次我尝试了一个更精确的问题:

我所拥有的:

  • ISet
    的巨大数据集(有限,但我以前浪费了数天的多核处理时间来计算它…)
  • 0到2n之间的输入值列表,n≤十七,
  • 我需要的是:

    3) [1],[2]的表,其中我将[2]的每个值映射为[1]的值

    处理过程:

    对于这个计算,我有一个公式,它接受一个位值(来自[2])和一组位置(来自[1]),并创建一个新的
    ISet
    。我需要找出原始集合中的哪一个与结果集合相等(即表中“A7”处的“单元格”可能指向“B”)

    天真的方式:

    计算新的
    ISet
    并使用
    .Contains(mySet)
    或[1]中值列表中的类似内容。在这个概念验证/pet项目的前几个版本中,我就是这么做的,当我开始喂大量的食物时,速度非常慢。是的,我用了剖析器。不,这不是系统中唯一慢的部分,但是我在这个简单的查找/映射中浪费了大量的时间

    最后,问题是:

    因为我基本上只需要重新映射到输入,所以我考虑为
    ISet
    列表创建一个散列值列表,对处理结果执行相同的操作,从而避免比较整个集合

    这是个好主意吗?你会认为这是过早的优化吗(我知道上面这种天真的方式太慢了,但是我应该先实现一些不那么聪明的东西吗?性能在这里非常重要,再想想运行时间)?有没有其他的建议来缓解这里的负担,或者我应该读些什么


    更新:很抱歉没有立即提供更好的解释或示例

    [1]的示例(注意:这些是真正可能的数据点,但显然是有限的):

    新列表(){
    new HashSet(){new Point(0,0)},
    新HashSet(){新点(0,0),新点(2,1)},
    新HashSet(){新点(0,1),新点(3,1)}
    }
    
    [2] 只是长度为n的布尔向量。对于n=2,它是

    • 0,0
    • 0,1
    • 1,0
    • 1,1
    基本上,我可以通过使用int或long来实现

    现在我有一个函数,它接受一个向量和一个
    ISet
    ,并返回一个新的
    ISet
    。这不是一个1:1的转换:一组5可能会导致一组11或其他。但是,生成的ISet保证是输入的一部分

    用字母表示一组点,用数字表示位向量,我从这里开始

    A B C D E F 1 2 3 4 5 6 7 A B C D E F 1. 2. 3. 4. 5. 6. 7. 最后我需要的是

    A B C D E F 1 - C A E - - 2 B C E F A - 3 ................ 4 ................ 5 ................ 6 F C B A - - 7 E - C A - D A B C D E F 1-CAE-- 2 B C E F A- 3. 4. 5. 6 F C B A-- 7 E-C A-D 在这些项目中有几个成本高昂的操作,一个是准备点集([1])。但现在这个问题是关于匹配的:我可以很容易地(或多或少,现在不那么重要)计算给定位向量的目标ISet和源ISet。现在我需要在原始设置中匹配/找到它

    整个beast将成为一个状态机,其中点集是一个有效状态。后来,我不关心单个的状态,我实际上可以通过任何方式(字母、索引等)引用它们。我只需要保持联系:

    1,B=>C


    更新:Eric询问是否可以使用哈希集。答案是肯定的,但前提是数据集保持足够小。我的问题(散列)是:对这个散列集使用散列算法是否可能/是个好主意?我的想法是:

    • 遍历
      ISet
      的(惰性生成的)列表/序列(我可以更改此类型,我只想强调它是一组数学点,没有重复)

      • 创建输入的更简单表示形式(散列?)并将其存储(在散列集中?)
      • 计算此输入的所有目标集,但只存储一个简单的表示(见上文)
      • 放弃这一套
    • 修复映射(相等哈希=相等状态)


    好主意?这有什么问题吗?我能想到的一个问题是冲突(可能性有多大?)-我不知道一个好的散列函数是如何开始的。

    好的,我想我至少现在理解了这个问题。让我看看能不能换个说法

    让我们先离开这里。我们将保持它的抽象性

    您有一个很大的列表L,其中包含引用类型S(用于“set”)的实例。当然,这样的列表在逻辑上是从自然数N到S的映射

    L: N --> S
    
    S的属性是可以比较两个实例的引用相等和值相等。也就是说,可以有两个引用不相等的S实例,但在逻辑上表示相同的值

    有一个函数F,它接受一个V类型的值(代表“vector”)和一个S类型的实例,并生成另一个S类型的实例

    F: (V, S) --> S
    
    此外,您知道,如果F从L中得到一个S的实例,那么得到的S实例的值将等于列表中的某个值,但不一定等于reference

    您面临的问题是:给定s的一个实例s,它是调用F的结果,哪个成员L(n)的值等于s

    是吗

    天真的方法——向下走L(1),L(2)。。。测试过程中设置的相等性将非常缓慢。至少在L的大小上是线性的

    我可以想出几种不同的方法来进行。最简单的是你最初的想法:让我做一个列表以外的东西。你能把它变成一个
    HashSet
    而不是
    List
    ?如果在S上实现哈希算法和相等方法,则可以构建快速查找表

    如果这不合适,我们将探索其他选择

    更新:

    F: (V, S) --> S