C# 置换查找算法(伪码)分析

C# 置换查找算法(伪码)分析,c#,algorithm,optimization,hash,random,C#,Algorithm,Optimization,Hash,Random,关于生成所有排列的一个问题让我想到了一些替代方法。我在考虑使用空间/运行时权衡,想知道人们是否可以在试图用C#实现它时批评这种方法和可能出现的问题 步骤如下: 给定同质元素的数据结构,计算结构中元素的数量 假设排列包含结构的所有元素,计算步骤1中值的阶乘 实例化类型的较新结构(字典)并初始化计数器 散列(??)步骤1中的种子结构,并将散列和集合的键/值对插入字典。将计数器增加1 随机洗牌(??)种子结构的顺序,散列它,然后尝试从步骤3将其插入字典 如果散列中存在冲突,请再次重复步骤5以获得新的顺

关于生成所有排列的一个问题让我想到了一些替代方法。我在考虑使用空间/运行时权衡,想知道人们是否可以在试图用C#实现它时批评这种方法和可能出现的问题

步骤如下:

  • 给定同质元素的数据结构,计算结构中元素的数量

  • 假设排列包含结构的所有元素,计算步骤1中值的阶乘

  • 实例化
    类型的较新结构(字典)并初始化计数器

  • 散列(??)步骤1中的种子结构,并将散列和集合的键/值对插入字典。将计数器增加1

  • 随机洗牌(??)种子结构的顺序,散列它,然后尝试从步骤3将其插入字典

  • 如果散列中存在冲突,请再次重复步骤5以获得新的顺序和散列并检查冲突。成功插入后,将计数器增加1

  • 重复步骤5和6,直到计数器等于步骤2中计算的阶乘

  • 使用某种随机化器(目前对我来说是一个黑匣子)这样做可能有助于在一个合适的时间范围内获得所有排列,以获得淫秽大小的数据集

    如果能从SO的伟人那里得到一些反馈,进一步分析这种方法,其目的是偏离这种性质的算法中流行的传统暴力方法,以及使用C#实现这种算法的后果,那将是非常好的


    感谢

    这似乎是一种将生成的排列顺序随机化的复杂方法。就时间效率而言,你不可能比“暴力”方法做得更好。

    与标准的已知方法相比,这种生成所有排列的方法效果不佳

    假设您有n个项目,M=n!排列

    这种生成方法期望在发现所有M之前生成M*lnM置换

    (有关可能的解释,请参见此答案:)

    另外,哈希函数是什么?对于一个合理的散列函数,我们可能必须很快开始处理非常大的整数问题(任何n>50都可以确定,不记得确切的截止点)

    此方法也会占用大量内存(所有排列的哈希表)

    即使假设散列是完美的,该方法也将采用预期的Omega(nMlogM)操作和保证的Omega(nM)空间,而标准的已知方法可以在O(M)时间和O(n)空间中实现

    作为一个起点,我建议人们可以阅读:这是相信O(nM)时间和O(n)空间,仍然比这个方法好得多


    请注意,如果必须生成所有置换,任何算法都必须采用ω(M)步骤,因此我上面提到的方法是最优的

    有没有比“暴力”方法做得更好的方法的例子?谢谢你精心起草的回复。这就是我一直在寻找的分析。这样做的目的不是建议一种“更好”/“更差”/“相当差”的方法,而是探索其他方法。作为科学界的一员,你的分析量化了缺点,但我认为在回答时,我们应该避免使用有点接近敌意的措辞。@Scu ray:对不起,我无意冒犯你。我会把它删掉的。@白痴:没问题。因此,用外行的话说,从时间的角度来看,问题源于随机化,在它真正缩小一个独特的安排之前,需要进行太多的尝试。从空间的角度来看,在存储简单散列就足够的情况下,在内存中反复存储整个集合会产生不必要的开销(考虑到散列函数是完美的)@sc_-ray:从时间的角度来看,是的,你很可能会遇到重复(例如,试试谷歌生日悖论)。MlogM时间是你在找到所有排列之前所需要的预期尝试次数。从空间使用的角度来看,即使你只存储紧凑的散列(而不是整个排列),空间是ω(M),而标准方法可以通过对上一个排列的元素重新排序来生成下一个排列,O(n)也是如此,这相当于节省了大量空间(例如:对于10个项目,而不是~40字节,您将使用~3MB)…对于100多个项目,ω(M)空间的使用使它变得不可能!(100!可能比宇宙中估计的原子数或其他类似的陈词滥调还要多…)