汉明数和双精度

2024-04-10

我正在玩生成汉明数 http://en.wikipedia.org/wiki/Regular_number在 Haskell 中,尝试改进明显的功能(请原谅函数的命名)

mergeUniq :: Ord a => [a] -> [a] -> [a]
mergeUniq (x:xs) (y:ys) = case x `compare` y of
                               EQ -> x : mergeUniq xs ys
                               LT -> x : mergeUniq xs (y:ys)
                               GT -> y : mergeUniq (x:xs) ys

powers :: [Integer]
powers = 1 : expand 2 `mergeUniq` expand 3 `mergeUniq` expand 5
  where
    expand factor = (factor *) <$> powers

I noticed that I can avoid the (slower) arbitrary precision Integer if I represent the numbers as the triple of the 2-, 3- and 5-exponents like data Power = Power { k2 :: !Int, k3 :: !Int, k5 :: !Int }, where the number is understood to be 2k2 * 3k3 * 5k5. The comparison of two Powers then becomes

instance Ord Power where
  p1 `compare` p2 = toComp (p1 `divP` gcdP) `compare` toComp (p2 `divP` gcdP)
    where
    divP p1 p2 = Power { k2 = k2 p1 - k2 p2, k3 = k3 p1 - k3 p2, k5 = k5 p1 - k5 p2 }
    gcdP = Power { k2 = min (k2 p1) (k2 p2), k3 = min (k3 p1) (k3 p2), k5 = min (k5 p1) (k5 p2) }
    toComp Power { .. } = fromIntegral k2 * log 2 + fromIntegral k3 * log 3 + fromIntegral k5 * log 5

So, very roughly speaking, to compare p₁ = 2i₁ * 3j₁ * 5k₁ and p₂ = 2i₂ * 3j₂ * 5k₂ we compare the logarithms of p₁ and p₂, which presumably fit Double. But actually we do even better: we first compute their GCD (by finding the mins of the corresponding exponents pairs — only Int arithmetic so far!), divide p₁ and p₂ by the GCD (by subtracting the mins from the corresponding exponents — also only Int arithmetic), and compare the logarithms of the results.

但是,考虑到我们经历了Doubles,最终会损失精度。这就是我提出问题的基础:

  1. When will the finite precision of Doubles bite me? That is, how to estimate the order of i, j, k for which the results of comparisons of 2i * 3j * 5k with numbers with "similar" exponents will become unreliable?
  2. 我们除以 GCD(这可能会大大降低此任务的指数)这一事实如何修改前一个问题的答案?

我做了一个实验,将这种方式生成的数字与通过任意精度算术生成的数字进行比较,直到第 1'000'000'000 个的所有汉明数都完全匹配(这花了我大约 15 分钟和 600 兆 RAM核实)。但这显然不是证据。


经验上 https://stackoverflow.com/a/12041774/849891,它高于大约 10 万亿分之一汉明数,或更高。

使用你漂亮的 GCD 技巧在这里对我们没有帮助,因为一些相邻的汉明数之间肯定没有公因数。

update:在线尝试关于ideone https://ideone.com/gHPmTo在其他地方,我们得到

4T  5.81s 22.2MB  -- 16 digits used.... still good
                  --  (as evidenced by the `True` below), but really pushing it.
((True,44531.6794,7.275957614183426e-11),(16348,16503,873),"2.3509E+13405")
-- isTruly  max        min logval           nth-Hamming       approx.
--  Sorted   logval      difference          as i,j,k          value
--            in band      in band                             in decimal
10T   11.13s 26.4MB
((True,60439.6639,7.275957614183426e-11),(18187,23771,1971),"1.4182E+18194")
13T   14.44s 30.4MB    ...still good
((True,65963.6432,5.820766091346741e-11),(28648,21308,1526),"1.0845E+19857")

---- same code on tio:
10T   16.77s
35T   38.84s 
((True,91766.4800,5.820766091346741e-11),(13824,2133,32112),"2.9045E+27624")
70T   59.57s
((True,115619.1575,5.820766091346741e-11),(13125,13687,34799),"6.8310E+34804")

---- on home machine:
100T: 368.13s
((True,130216.1408,5.820766091346741e-11),(88324,876,17444),"9.2111E+39198")

140T: 466.69s
((True,145671.6480,5.820766091346741e-11),(9918,24002,42082),"3.4322E+43851")

170T: 383.26s         ---FAULTY---
((False,155411.2501,0.0),(77201,27980,14584),"2.80508E+46783")
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

汉明数和双精度 的相关文章

  • 识别鼠标移动的算法

    我想知道是否有任何研究 算法可以指定鼠标在识别 等字符时的偏差量使用鼠标绘制 某种光学字符识别 但可能是一个更简单的版本 是否有某种算法可以让我说用户绘制的问号确实是一个问号 而不是其他具有一定准确性的东西 就像 Windows 平板电脑软
  • 为什么haskell中的递归列表这么慢?

    我对 Haskell 很陌生 我在 Haskell 中定义了一个函数 febs Integral a gt a gt a febs n n lt 0 0 n 1 1 n 2 1 otherwise febs n 1 febs n 2 但是
  • 对矩阵进行舍入,保留行和列总计

    想要 以保留行和列总计的方式对矩阵进行舍入的 伪 代码 问题从向量开始 X and Y of 非负整数 with Sum X Sum Y 想要圆X Y Sum X 同时保留行和列总计 这是婚姻问题的一种 Xa需要进行一定次数的握手 拨打该号
  • 为什么《破解编码面试》这个例子的时间复杂度是O(k c^k)?

    该问题来自 破解编码面试 第 6 版 问题 V1 11 以下代码打印长度为 k 的所有字符串 其中字符 是按排序顺序排列的 它通过生成所有长度的字符串来做到这一点 k 然后检查每个是否已排序 什么是运行时间 package QVI 11 P
  • 处理许多不相关的类型时避免样板

    我正在编写处理以下值的代码语言 扩展 注释 语法 http hackage haskell org packages archive haskell src exts 1 1 4 doc html Language Haskell Exts
  • 图像算法上的物体计数

    我又接到学校任务了 这次 我的老师给我的任务是创建算法来计算图片上有多少只鸭子 该图与此类似 我想我应该使用模式识别来搜索上面有多少只鸭子 但我不知道每只鸭子适合哪种图案 我认为你可以通过分割鸭嘴并计算鸭嘴的数量来解决这个问题连接的组件 h
  • Haskell 测量函数性能

    在 Haskell 中 我如何 简单地 测量函数的性能 例如 运行需要多长时间 或者需要多少内存 我知道分析 但是 是否有一种更简单的方法不需要我对代码进行太多更改 测量运行需要多长时间以及需要多少内存是两个独立的问题 即 基准测试和分析
  • 用于计算三角函数、对数或类似函数的算法。仅限加减法

    我正在修复 Ascota 170 古董机械可编程计算机 它已经开始工作了 现在我正在寻找一种算法来展示其功能 例如计算三角或对数表 或类似的东西 不幸的是 从数学运算来看 计算机只能进行整数的加减法 从 1E12到1E12的55个寄存器 甚
  • HUGE_VALF 和 INFINITY 常量之间的区别

    在 OpenCL 中 有两个代表无穷大的浮点数学常数 其中之一很简单INFINITY 另一个 HUGE VALF 求值为 无穷大 这两者有什么区别 求值至 无穷大是什么意思 HUGE VALF是一个旧名称 允许不支持无穷大的浮点系统 例如
  • 在 haskell 中处理 IO 与纯代码

    我正在编写一个shell脚本 我在haskell中的第一个非示例 它应该列出一个目录 获取每个文件大小 进行一些字符串操作 纯代码 然后重命名一些文件 我不确定我做错了什么 所以有两个问题 我应该如何安排这样的程序中的代码 我有一个具体问题
  • 如果是整数,则使用 sprintf 格式化没有小数位的浮点数

    最初 我使用 sprintf 和始终保留 2 位小数的浮点数 使用以下代码 static void MyFunc char buffer const float percentage sprintf buffer 2f percentage
  • 处理流星中的长服务器端计算

    我正在使用 jimp https www npmjs com package jimp https www npmjs com package jimp 在meteor JS中生成图像服务器端 换句话说 我正在使用递归算法 计算 图像的像素
  • 有效地合并两个数组 - 一个已排序,另一个未排序

    我正在解决一个问题 该问题有一个由 n 个元素组成的排序数组 后跟一个未排序的长度数组 O logn O 平方 n 如何最有效地对整个列表进行排序 在上述两种情况下我应该使用哪种排序 由于将单个元素插入数组并保持其排序是O n 你不可能变得
  • 素数生成器算法

    我一直在尝试解决素数生成算法的SPOJ问题 这是问题 彼得想为他的密码系统生成一些素数 帮助 他 你的任务是生成两个给定之间的所有素数 数字 Input 输入以单行中测试用例的数量 t 开始 t Output 对于每个测试用例 打印所有素数
  • 从原点开始在离散 2D 网格上迭代向外螺旋的算法

    例如 这是预期螺旋的形状 以及迭代的每个步骤 y 16 15 14 13 12 17 4 3 2 11 18 5 0 1 10 x 19 6 7 8 9 20 21 22 23 24 其中线条是 x 轴和 y 轴 以下是算法每次迭代 返回
  • 线段树java实现[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 你知道 二进制 的良好实现吗线段树 http en wikipedia org wiki Segmen
  • 如何手动(按位)执行(浮动)x?

    现在 这是我应该实现的函数的函数头 float from int Return bit level equivalent of expression float x Result is returned as unsigned int bu
  • 有什么方法可以在 do / while / let 块中打印出变量的类型吗?

    有没有办法打印出嵌套变量的推断类型ghci 考虑代码 let f g where g x Int x 那么 最好查询一下类型g e g t f g会打印出Int gt Int 您可以通过给出适当的错误类型注释并检查错误消息来诱骗此信息 Ma
  • “包含字符串”的快速索引

    在我的应用程序中 我有多达数百万个短字符串 大部分短于 32 个字符 我想实现一个带有附加列表的搜索框 该列表仅包含包含在搜索框中输入的整个字符串的元素 如何预先建立索引来快速找到此类字符串 所有排序的 STL 容器都会检查整个字符串 对于
  • 如何在 C# 中以编程方式创建柔和的颜色?

    根据所需的颜色数量均匀分布地生成它们 如果指定的计数为 8 则看起来像这样 List

随机推荐