algorithm - 你如何有效地解决这个对数不等式?

标签 algorithm equation inequality

不等式为:nlogn <= a(n为自然数,log以10为底)。问题:n 的最大值是多少?

我的解决方案是扫描 n = 1 到无穷大(第 1 步),直到到达 nlogn > a 的点。返回的结果将是 n - 1

但我发现当 a 非常大时,这样做效率不高。有没有人知道如何解决它?

最佳答案

我正确地为comingstorm的解决方案做了代数计算并实现了。在我的机器上,牛顿法比二进制搜索高 4 倍。我已经在所有非负 32 位整数上测试了 newton()

#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <time.h>

static int newton(double a) {
    if (a < 2.0 * log10(2.0)) {
        return 1;
    } else if (a < 3.0 * log10(3.0)) {
        return 2;
    }
    double a_log_10 = a * log(10);
    double x = a / log10(a);
    x = (x + a_log_10) / (1.0 + log(x));
    x = (x + a_log_10) / (1.0 + log(x));
    double n = floor(x);
    if (n * log10(n) > a) {
        n--;
    } else if ((n + 1.0) * log10(n + 1.0) <= a) {
        n++;
    }
    return n;
}

static int binarysearch(double a) {
    double l = floor(a / log10(a));
    double u = floor(a) + 1.0;
    while (1) {
        double m = floor((l + u) / 2.0);
        if (m == l) break;
        if (m * log10(m) > a) {
            u = m;
        } else {
            l = m;
        }
    }
    return l;
}

static void benchmark(const char *name, int (*solve)(double)) {
    clock_t start = clock();
    for (int a = 1 << 22; a >= 10; a--) {
        int n = solve(a);
        assert(n * log10(n) <= a);
        assert((n + 1) * log10(n + 1) > a);
    }
    printf("%s: %.2f\n", name, (clock() - start) / (double)CLOCKS_PER_SEC);
}

int main(int argc, char *argv[]) {
    benchmark("newton", newton);
    benchmark("binarysearch", binarysearch);
}

关于algorithm - 你如何有效地解决这个对数不等式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7455344/

相关文章:

python - 生成递归以找到具有最大总和的子列表

javascript - 如何对数百个 Canvas 圆进行高性能重叠/碰撞检测?

algorithm - N个矩形交集

algorithm - 箱子堆叠问题

c++ - 中缀对话的后缀

Python - 检查列表中的所有元素是否满足不等式

r - 用deqn和roxygen记录方程式

r - 如何使用ggplot2填充stat_poly_eq方程(ggpmisc)的背景?

R函数用阴影绘制不等式

import - Ada:导入不等式运算符 "/="