我的代码有时会给我错误的输出,如何解决呢?

时间:2019-07-11 05:08:36

标签: python

我正在尝试解决这个问题:“您的任务是建造一栋将要堆积n个立方体的建筑物。底部的立方体的体积为n ^ 3,上方的立方体的体积为(n-1)^ 3,依此类推,直到顶部的立方体的体积为1 ^ 3。 您将获得建筑物的总体积m。给定m,您可以找到要构建的多维数据集个数n吗? 函数findNb的参数(find_nb,find-nb,findNb)将是整数m,您必须返回整数n,例如n ^ 3 +(n-1)^ 3 + ... + 1 ^ 3 = m(如果存在)或-1(如果不存在)。

我试图首先创建一个算术序列,然后将其转换为带有算术序列第n个项的sigma和,得到一个可以与m进行比较的公式。

我使用了这段代码,可以将其工作70%到80%,但大多数计算是正确的,但有些却不正确。

import math


def find_nb(m):
    n = 0
    while n < 100000:
        if (math.pow(((math.pow(n, 2))+n), 2)) == 4*m:
            return n
            break
        n += 1
    return -1


print(find_nb(4183059834009))
>>> output 2022, which is correct
print(find_nb(24723578342962))
>>> output -1, which is also correct
print(find_nb(4837083252765022010))
>>> real output -1, which is incorrect
>>> expected output 57323

2 个答案:

答案 0 :(得分:3)

如上所述,这是一个数学问题,主要是我比较擅长的:)。 很抱歉在线数学公式,因为我无法进行任何数学公式渲染(在SO中)。

我看不到您的代码有任何问题,并且我相信您的示例测试用例是错误的。但是,我仍将在下面给出优化“技巧”,以使您的代码更快地运行

首先,您知道1 ^ 3和n ^ 3之间的多维数据集的总和为n ^ 2(n + 1)^ 2/4。因此,我们想找到方程的整数解

n^2(n+1)^2/4 == m,即n^4+2n^3+n^2 - 4m=0

n从1(或者在您的情况下为2021)到100000运行循环是低效率的。首先,如果m为大数(1e100 +),则代码的复杂度为O(n ^ 0.25)。考虑到Python的运行时,只有m小于1e32左右时,您才能及时运行代码。

要优化代码,您有两种方法。

1)使用 Binary Search 。我不会在这里详细介绍,但是基本上,您可以减半进行简单比较。对于首字母bounds,可以使用lower = 0 & upper = k。下面将为k提供一个更好的界限,但是现在让我们使用k = m

复杂度:O(log(k))= O(log(m))

m的可行范围:m <10 ^(3e7)

2)使用全能的 Newton-Raphson !使用迭代公式x_(n+1) = x_n - f(x_n) / f'(x_n),其中f'(x)可以显式计算,并且有一个合理的初始猜测,再说一次k = m,复杂度为(我相信)O(log(k)) + O(1)= O(log(m))。

复杂度:O(log(k))= O(log(m))

m的可行范围:m <10 ^(3e7)

最后,在上述方法中,我将对k进行更好的初步猜测,这也是Ian对this question的回答。自n^4+2n^3+n^2 = O(n^4)起,我们实际上可以采用k ~ m^0.25 = (m^0.5)^0.5。为了计算这一点,我们可以使用k = 2^(log(k)/4),其中log是2的底数。该日志应为O(1),但是我不确定大数字/动态大小(在Python中为int)。不是理论家。使用这个更好的猜测和牛顿-拉夫森,因为从结果猜测是在恒定范围内,该算法接近O(1)。再次,检查链接以更好地理解。

最后

由于您的目标是确定n是否存在,从而使方程“完全满足”,因此请使用Newton-Raphson进行迭代,直到下一个猜测小于当前猜测的0.5。如果您的实现是“软盘式”,那么您也可以在猜测的范围内进行+/- 10的操作,以确保找到解决方案。

答案 1 :(得分:0)

我认为这是一个数学问题,而不是编程问题。

首先,我建议您从输入m的函数开始进行迭代。现在,您可以任意初始化n值(当然,这可能是一个问题的要求),但是我认为有一些方法可以对其进行优化。也许,也许您可​​以从多维数据集的根进行迭代,所以如果n达到零,或者在任何时候总和变得小于m,您可以放心地假设没有可以建造的建筑物。

第二,从求和中得出的方程似乎不正确。我替换了您期望的n,然后在您的if子句中的条件中输入了m,但它们不匹配。因此,要么1)您的方程式错误,要么2)预期输出错误。我建议您重新考虑一下条件的推导。您是否正在使用多维数据集分解的总和?您可能忽略了一些极端情况(也许是奇怪的n),但是我的数学很生疏,所以我无济于事。

当然,如上所述,break是不必要的,永远不会执行。