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

发布于 2024-12-05 05:56:05 字数 166 浏览 0 评论 0原文

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

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

但我发现当 a 很大时这效率不高。有谁知道如何解决它?

The inequality is: nlogn <= a (n is natural number, log is based of 10). Question: what is the maximum value of n possible?

My solution is to scan n = 1 to infinity (step 1) until getting to the point where nlogn > a. Result returned would be n - 1

But I found out that this is not efficient when a is very large. Does anyone have a good idea how to solve it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

别忘他 2024-12-12 05:56:05

我正确地计算了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);
}

I did the algebra for comingstorm's solution properly and made an implementation. On my machine, Newton's method beats binary search by a factor of 4. I have tested newton() on all nonnegative 32-bit integers.

#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);
}
惜醉颜 2024-12-12 05:56:05

通过二分查找来完成。起始间隔可以是 (1,a) 或 (sqrt(a),a)。

Do it with a binary search. The starting interval can be (1,a) or (sqrt(a),a).

幸福%小乖 2024-12-12 05:56:05

如果求解方程 nlogn = a,则可以避免每次进行比较时都执行该计算。该方程是一个超越方程,因此恒定时间迭代可以获得一个相当好的结果很好的近似。然后对您的数据执行二分搜索

procedure solve_transcendental
   n = 50
   for i = 1 .. 20
      n = a / log(n)
   end
end

If you solve the equation nlogn = a, you can avoid performing that calculation every time you do a comparison. The equation is a Transcendental equation, so a constant time iteration could get you a result that is a fairly good approximation. Then perform a Binary Search on your data.

procedure solve_transcendental
   n = 50
   for i = 1 .. 20
      n = a / log(n)
   end
end
春夜浅 2024-12-12 05:56:05

二分查找是一个很好可靠的答案。求解此类方程的另一种方法是将它们重写为 x=f(x),然后计算出 f(x)、f(f(x))、f(f(f(x))) 等,以及希望结果收敛。如果 |f'(x)| 则有希望实现这一点< 1. 将 n log n = a 重写为 n = a / log n 在实践中似乎效果出奇地好。

Binary search is a good reliable answer. Another way to solve equations like this is to rewrite them as x=f(x) and then work out f(x), f(f(x)), f(f(f(x))) and so on, and hope that the result converges. There is hope for this if |f'(x)| < 1. Rewriting n log n = a as n = a / log n appears to work surprisingly well in practice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文