- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个算法可以解释为将数字线分成相等数量的 block 。为简单起见,我将坚持 [0,1),它将像这样划分:
0|----|----|----|----|1
我需要做的是获取一系列数字 [j,k) 并找到最大个 block ,N,直到某个最大 M,这将划分数字行[j,k) 仍然都属于同一个“bin”。这比听起来更棘手,因为范围可以像这样跨越垃圾桶:
j|-|k
0|----|----|----|----|1
因此在完全包含范围之前,您可能必须达到相当低的数字。更重要的是,随着 bin 数量的增加,范围可能会移入和移出单个 bin,因此存在局部最小值。
显而易见的答案是从 M 个 bin 开始,然后减少数量直到范围落入一个 bin 中。但是,我想知道是否有比枚举所有可能的除法更快的方法,因为我的最大数目可以相当大(8000 万左右)。
有更好的算法吗?
最佳答案
在这里我想给出另一个启发式,它不同于 btilly 的。
任务是找到整数 m
和 n
这样 m / n <= j < k <= (m + 1) / n
, 与 n
尽可能大(但仍低于 M
)。
直觉上,分数 m / n
更可取靠近j
.这导致了使用 continued fractions 的想法.
我提出的算法非常简单:
j
的所有连分数使用减号(这样分数总是从上面接近j
),直到分母超过M
;m / n
, 找出最大的整数 i >= 0
这样 k <= (m * i + 1) / (n * i)
和 n * i <= M
, 并替换分数 m / n
与 (m * i) / (n * i)
;算法在j
中不对称和 k
.因此有一个类似的 k
-version,一般情况下不应该给出相同的答案,以便您可以从两个结果中选择较大的一个。
例子:这里我以btilly的例子:j = 0.6
和 k = 0.65
, 但我会选择 M = 10
.
我将首先浏览 j
-程序。计算 j
的连分数展开式,我们计算:
0.6
= 0 + 0.6
= 0 + 1 / (2 - 0.3333)
= 0 + 1 / (2 - 1 / (3 - 0))
自 0.6
是有理数,展开会在无穷多步后终止。相应的分数是:
0 = 0 / 1
0 + 1 / 2 = 1 / 2
0 + 1 / (2 - 1 / 3) = 3 / 5
计算对应的i
在第 2 步中,我们将三个派系替换为:
0 / 1 = 0 / 1
1 / 2 = 3 / 6
3 / 5 = 6 / 10
最大分母由 6 / 10
给出.
继续上面的例子,对应的k
-程序如下:
0.65
= 1 - 0.35
= 1 - 1 / (3 - 0.1429)
= 1 - 1 / (3 - 1 / (7 - 0))
因此相应的分数:
1 = 1 / 1
1 - 1 / 3 = 2 / 3
1 - 1 / (3 - 1 / 7) = 13 / 20
通过第 2 步,我们得到:
1 / 1 = 2 / 2
2 / 3 = 6 / 9
13 / 20 = 0 / 0 (this is because 20 is already bigger than M = 10)
最大分母由 6 / 9
给出.
编辑:实验结果。
令我惊讶的是,该算法的效果比我想象的要好。
我用绑定(bind) M
做了下面的实验忽略(等效地,一个人可以取 M
足够大)。
在每一轮中,我都会生成一对 (j, k)
区间内均匀分布的随机数 [0, 1)
与 j < k
.如有差异k - j
小于 1e-4
,我丢弃了这对,使这一轮无效。否则我计算出真正的结果 trueN
使用朴素算法,并计算启发式结果heurN
使用我的算法,并将它们添加到统计数据中。这适用于 1e6 轮。
结果如下:
effective round = 999789
sum of trueN = 14013312
sum of heurN = 13907575
correct percentage = 99.2262 %
average quotient = 0.999415
correct percentage
是有效回合的百分比 trueN
等于heurN
, 和 average quotient
是商的平均值 heurN / trueN
对于所有有效回合。
因此该方法在 99% 以上的情况下给出了正确答案。
我还用较小的 M
做了实验值,结果相似。
关于algorithm - 最大的除数使得两个数除以它四舍五入到相同的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36988167/
我有这个“科学应用程序”,其中 Single 值在显示在 UI 中之前应该四舍五入。根据this MSDN article ,由于“精度损失”,Math.Round(Double, Int32) 方法
这个问题类似于Chrome 37 calc rounding 但实际问题有点复杂,提供的解决方案不适用于这种情况: #outerDiv, #leftDiv, #middleDiv, #rightDiv
假设有一堆从 pnorm() 返回的数据,这样您就有了 .0003ish 和 .9999ish 之间的数字。 numbers <- round(rnorm(n = 10000, mean =
我想有效地将unsigneda整数除以2的任意幂,然后取整。所以我在数学上想要的是ceiling(p/q)0。在C语言中,不利用q受限域的Strawman实现可能类似于以下function1: /
我正在尝试获取 #value_box 的值以显示 100.5 但它一直在向上舍入。有谁知道我可以做些什么来让它显示小数位? jsfiddle //returns 101 $("#value_box
我有一段 JavaScript 代码 shipingcostnumber * parseInt(tax) / 100 + shipingcostnumber 返回数字为6655.866558,因此我将
我有一个关于 PostgreSQL 9.2 中 float 的新手问题。 是否有直接舍入 float 的函数,即不必先将数字转换为数字类型? 另外,我想知道是否有一个函数可以按任意度量单位舍入,例如最
这个问题已经有答案了: Rounding to nearest 100 (7 个回答) 已关闭10 年前。 我正在尝试将数字四舍五入到 100。 示例: 1340 should become 1400
我试图找出使用整数存储在列表中的其他两个数字之间的任何n在整数列表中找到最接近的值ROUNDED DOWN的最佳方法。在这种情况下,所有整数都将始终是无符号的,以防万一。 假设如下: 列表始终从0开始
我想将一个 BigDecimal 四舍五入到小数点后两位,但是当使用 round 方法时,它似乎没有双舍入: BigDecimal.new('43382.0249').round(2).to_s('F
我正在使用格式如下的财务数据进行计算: . 基本上,在我的程序中我遇到了一个浮点错误。例如,如果我有: 11.09 - (11.09 * 0.005) = 11.03455 我希望能够使用 11.03
有整型变量,电压单位为毫伏。 signed int voltage_mv = 134; //134mV 我有 2 段显示,我想显示百分之一伏特。 如何在一次操作中将毫伏转换为百分之一伏?没有 IF 语
这是我将数字四舍五入到两位小数的函数,但是当四舍五入的数字为 1.50 时,它似乎忽略尾随零并只返回 1.5 public static double roundOff(double number)
您好,我在将数字四舍五入到 -0 而不是 0 时遇到了问题 代码: 输出:-0 预期输出:0 我一直在寻找任何解决方案,但没有找到。 请解释并帮助我为什么它四舍五入为 -0 而不是 0?谢谢 最佳答
我正在使用 Java 的 Random 生成随机数:1.0、1.1 - 10 Random random = new Random(); return (double) ((random.nextIn
基本上,我有一个数字: 我基本上想做一些数学运算来创建这个数字 80。 如果数字是 62.7777777778,则数字将为 60。 我希望数字像这样四舍五入: 20, 40, 60, 80, 100
我希望显示来自 NSDate 对象的月数。 //Make Date Six Months In The Future NSCalendar *calendar = [[NSCalendar alloc
下面是一些小代码来说明我所看到的 float floater = 59.999f; DecimalFormat df = new DecimalFormat("00.0"); System.out.p
我现在开始使用 android 和 java,但遇到了问题。 I have a result x = 206.0548. And y = 206, both of type double How do
我有一个 ruby 散列数组,其中包含两个键,'tier' 和 'price'。对于给定的价格,我想退回等级。 这对于精确匹配来说已经足够简单了,但是我如何通过将我的输入值四舍五入到数组中的下一个
我是一名优秀的程序员,十分优秀!