Python 我能说这是动态规划吗?

Python 我能说这是动态规划吗?,python,dynamic-programming,Python,Dynamic Programming,我是动态规划的新手,从我的理解来看,动态规划就是使用计算的结果来检查函数是否正确。在一次采访中,我被要求实施一种方法来检查n是否为二的幂。所以,我想到了这个 def isPowerOfTwo(self, n): power_of_two = [1] is_power_of_two = False if n == 0: return False if n == 1: return True while True:

我是动态规划的新手,从我的理解来看,动态规划就是使用计算的结果来检查函数是否正确。在一次采访中,我被要求实施一种方法来检查
n
是否为二的幂。所以,我想到了这个

def isPowerOfTwo(self, n):
    power_of_two = [1]
    is_power_of_two = False
    if n == 0:
        return False

    if n == 1:
        return True

    while True:
        power_of_two.append(power_of_two[-1] * 2)
        if n == power_of_two[-1]:
            is_power_of_two = True
            break

        if power_of_two[-1] > n:
            break

    return is_power_of_two
维基百科:

在数学、计算机科学、经济学和生物信息学中,动态规划是一种通过将复杂问题分解为一组更简单的子问题来解决复杂问题的方法

然而,这似乎主要针对优化问题,确定N是否为2的幂通常不作为优化问题

来自“计算机编程中的动态编程”一节:

要使动态规划适用,问题必须具有两个关键属性:最优子结构和重叠子问题。如果一个问题可以通过组合非重叠子问题的最优解来解决,则该策略称为“分而治之”。这就是为什么mergesort和quicksort没有被归类为动态规划问题的原因

最优子结构意味着给定优化问题的解可以通过其子问题的最优解的组合来获得。因此,设计动态规划解决方案的第一步是检查问题是否表现出这样的最优子结构。这种最优子结构通常用递归的方法来描述。例如,给定一个图G=(V,E),从一个顶点u到一个顶点V的最短路径p展示了最优子结构:取该最短路径p上的任何中间顶点w。如果p确实是最短路径,那么它可以被分成从u到w的子路径p1和从w到v的子路径p2,这样,这些子路径实际上是对应顶点之间的最短路径

重叠子问题意味着子问题的空间必须很小,也就是说,任何解决问题的递归算法都应该反复解决相同的子问题,而不是生成新的子问题。例如,考虑生成Fibonacci级数的递归公式:FI= FI−1+Fi−2,基本情况F1=F2=1。然后F43=F42+F41,F42=F41+F40。现在F41正在F43和F42的递归子树中求解。即使子问题的总数实际上很小(只有43个),但如果我们采用这样一种简单的递归解决方案,我们最终还是会一遍又一遍地解决相同的问题。动态规划考虑到了这一事实,每个子问题只解一次

虽然“N/2是2的幂吗?”是一个与“N是2的幂吗?”相关的子问题,我们可以编写一个例程,只解决一次这类子问题,但我们没有斐波那契序列中存在的重叠。如果我们这样做了,递归将不会很好地工作。在这里,是的。向递归中添加记忆是一种自上而下的DP技术,但如果递归中的O(log2n)时间是可接受的,则实际上不需要这样做

它看起来不像是将问题分解成更小的部分,而是构建了一个2次幂的列表(虽然不缓存列表,但每次都要构建它,但缓存或不缓存并不意味着它是或不是动态编程),并测试输入是否在列表中,如果不在列表中,是否可以通过扩展列表找到它。虽然我认为您的测试还可以,但与动态编程的联系更加脆弱

这里有一些其他的方法来测试这一点

测试一个数字是否为2的幂的一种方法是用基数2表示它,并确保只有一位设置为1,其余为零。许多语言都有一种方法可以获得整数的另一种基表示形式。2的幂也有独特的八进制和十六进制字符串表示

另一种方法是对n==2返回True,如果是非整数或奇数mod 2,则返回False,否则测试n/2是否是递归的2的幂。许多数学动态规划是递归的

def isPowerOf2(n):
        if n%2==1:
            return False
        if n==2:
            return True
        else:
            return isPowerOf2(n/2)
我们可以按如下方式键入检查并记录:

powers_of_2 = [2]
def isPowerOf2(n):
    if type(n)!=type(1):
        raise TypeError("isPowerOf2(): integer value required")
    if n%2==1:
        return False
    if n in powers_of_2:
        return True
    if n<powers_of_2[-1]:
        return False
    else:
        result =  isPowerOf2(n/2)
        if result:
            powers_of_2.append(n)
        return result
有关更简短的内容,请参见@Tris Nefzger的建议:;还可以检查log(N)/log(2)以查看它是否接近整数值,将2计算为该幂,并测试是否相等。最后两种方法都不是动态规划,但在实践中可能更适合这样一个简单的任务。

维基百科:

在数学、计算机科学、经济学和生物信息学中,动态规划是一种通过将复杂问题分解为一组更简单的子问题来解决复杂问题的方法

然而,这似乎主要针对优化问题,确定N是否为2的幂通常不作为优化问题

来自“计算机编程中的动态编程”一节:

要使动态规划适用,问题必须具有两个关键属性:最优子结构和重叠子问题。如果一个问题可以通过组合非重叠子问题的最优解来解决,则该策略称为“分而治之”。这就是为什么mergesort和quicksort没有被归类为动态规划问题的原因

最优子结构意味着给定优化问题的解可以通过其子问题的最优解的组合来获得。因此,设计动态规划解决方案的第一步是检查问题是否表现出这样的最优子结构。这种最优子结构通常用递归的方法来描述。对于
>>> import power2 # name of our python code script file
>>> power2.isPowerOf2(256)
True
>>> power2.powers_of_2
[2, 4, 8, 16, 32, 64, 128, 256]
def is_power_of_two(n):
    results = {}
    for i in range(1, n + 1):
        if i == 2:
            results[i] = True
        elif i % 2 != 0:
            results[i] = False
        else:
            results[i] = results[i/2]
    return results[n]