按间隔排列的汉明数

2024-05-11

这是生成汉明数序列(又名常规数字 https://en.wikipedia.org/wiki/Regular_number, 5-平滑数 https://en.wikipedia.org/wiki/Smooth_number)基于序列中一个数字到下一个数字的间隔。以下是所述间隔的示例图:

因此,将一个数字与下一个数字分开的离散间隔数量相对有限,并且随着 H 的增加,间隔会变小。人们经常注意到,汉明数随着大小的增加而变得越来越稀疏,这在绝对意义上是如此,但在另一种意义上(按比例)它们变得更接近。

基本上,随着 H 的增加,2^i*3^j*5^k(其中 i、j、k 是正整数或负整数)有更大的机会产生接近 1.0 的分数。

事实证明,只有 119 个间隔(i,j,k 三元组)的表涵盖了最多大约 10^10000 的汉明数。这大约是前 1.59 万亿个汉明数。这样一个表(C头文件),按照区间大小从小到大排序,就是here https://github.com/jmknapp/hammingnumbers/blob/master/hamseq.h。给定一个汉明数,要找到下一个,所需要做的就是找到表中的第一个条目,其中乘法(相应指数的加法)将产生 i、j 和 k 的正幂结果。

例如,第一百万个汉明数是 2^55*3^47*5^64,大约是 5.1931278e83。之后的下一个汉明数是 2^38*3^109*5^29 或大约 5.1938179e83。第一个合适的表条目是:

{-17,62,-35}, // 1.000132901540844

因此,虽然这些数字之间的间隔约为 7e79,但它们的比率为 1.000132901540844。要找到下一个数字,在最坏的情况下只需尝试最多 119 个条目,仅涉及加法和比较(无乘法)。此外,每个条目只有 3 个短整数的表需要不到 1kb 的内存。该算法基本上在内存上是 O(1),在时间上是 O(n),其中 n 是序列的长度。

加快速度的一种方法是,不要每次都从第 0 个索引开始搜索表,而是将表条目列表限制为仅搜索那些根据经验已知在给定范围内接替给定条目的条目(n

{11,{47,55,58,65,66,68,70,72,73,75,76}},

因此,根据经验发现,该特定索引后面仅跟随列出的 11 个不同索引,因此这些是唯一搜索的索引。

这样做可以将算法速度提高 4 倍左右,已实现here https://github.com/jmknapp/hammingnumbers/blob/master/hamseq.c(C 代码)以及头文件 https://github.com/jmknapp/hammingnumbers/blob/master/hamseq.h多于。下面是 i7-2600 3.4GHz 机器上的执行时间图:

我相信这与最先进的技术相比是有利的——是这样吗?

The Hamming problem is sometimes reduced to just finding the nth Hamming number without generating all the intermediate values. Adapting the above technique to a well-known scheme of just enumerating the Hamming numbers in a band around the desired range gives this plot of execution time: enter image description here

因此,只需不到 2 秒即可找到第 1.59 万亿个汉明数。其 C 代码是here https://github.com/jmknapp/hammingnumbers/blob/master/hamnum.c。至少在给定的范围内,这是否也能与现有技术相媲美?

编辑:n 的边界(1.59e12,汉明数高达约 10^10000)是根据特定机器选择的,其中希望 i、j、k 是短整数,并且对执行速度也有合理的期望。可以生成更大的表,例如一个包含 200 个条目的表将允许 n 高达约 1e18(汉明数高达约 10^85000)。

另一个问题是如何进一步加快速度。一个潜在的领域:事实证明,某些表条目比其他表条目更频繁地被命中,并且它们有相应更大的后继者列表需要检查。例如,当生成前 1.59e12 个数字时,该条目被 46% 的迭代命中:

{-7470,2791,1312}

它有 23 种可能的不同后继者。也许基于其他参数(例如,先前遍历的条目的历史记录)缩小范围的某种方法会有所帮助,尽管没有太多空间用于昂贵的操作。

EDIT #2:

有关生成表格的一些信息,基本上有六类分数 2^i*3^j*5^k,其中 i,j,k 是正整数或负整数:分子中只有 2,3 或 5 的分数,以及分母只有 2、3 或 5 的分数。例如,对于分子中只有 2 的类:

f = 2^i/(3^j*5^k),i > 0 且 j,k >= 0

计算此类分数的间隔的 C 程序是here https://github.com/jmknapp/hammingnumbers/blob/master/n2.c。对于大约 10^10000 的汉明数,它会在几秒钟内运行。它可能会变得更有效率。

对其他 5 类分数重复类似的过程会产生 6 个列表。按间隔大小对它们进行排序并删除重复项即可生成完整的表格。


The triples enumeration is ~ n2/3 but the sorting of the band is ~ n2/3 log (n2/3) i.e. ~ n2/3 log n. This obviously doesn't change even with ~ n1/3 band space scheme.

Indeed the empirical complexities are seen in practice as ~ n0.7.

I am yet to understand your algorithm fully, but the evidence you presented https://chat.stackoverflow.com/transcript/message/39753573#39753573 strongly suggests the pure ~ n2/3 operation, which would constitute a clear and significant improvement over the previous state of the art, absolutely.

在我看来,如果需要生成整个序列才能找到算法所基于的“间隔”(比率),情况就不是这样了。但由于您是独立生成它们的,正如您后来的编辑似乎所暗示的那样,这根本不是障碍。

更正:如果我们只对n序列中的第一个成员,则不需要对带进行完整排序;O(n) 选择第 k 个最大的算法确实存在。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

按间隔排列的汉明数 的相关文章

  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 为什么 GCC 不允许我创建“内联静态 std::stringstream”?

    我将直接前往 MCVE include
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐