【问题标题】:Primitive Calculator - Dynamic & Recursive approach原始计算器 - 动态和递归方法
【发布时间】:2021-11-14 22:03:33
【问题描述】:

我尝试使用动态和递归方法解决原始计算器问题,对于较小的输入效果很好,但对于较大的输入需要很长时间(例如:96234)。

给你一个原始计算器,它可以执行以下三个操作 当前数字????:乘????乘以 2,乘 ???? 3,或加 1 到????。你的目标是 正整数??? 从数字 1 开始。

import sys
def optimal_sequence(n,memo={}):
    
    
    if n in memo:
        return memo[n]
    if (n==1):
        return 0
    c1 = 1+optimal_sequence(n-1,memo)
        
    c2 = float('inf')
    if n % 2 == 0  :
        c2 = 1+optimal_sequence(n // 2,memo)
        
    c3 = float('inf')
    if n % 3 == 0 :
        c3 = 1+optimal_sequence(n // 3,memo)
    
    c = min(c1,c2,c3)
    memo[n] = c
    
    return c

input = sys.stdin.read()
n = int(input)
sequence = optimal_sequence(n)
print(sequence)  # Only printing optimal no. of operations

任何人都可以指出递归解决方案中的问题,因为它可以通过使用 for 循环正常工作。

【问题讨论】:

  • 你说它适用于小数字。您遇到大数字的错误是什么?
  • 需要很长时间
  • @Ben10101 如果代码可以运行,但您需要优化它(正如您所说,运行时间很长),这篇文章不是针对 StackOverflow,而是针对 CodeReview:codereview.stackexchange.com
  • 这是一种误导:一个需要很长时间的进程不一定有错误。当输出错误时,您可以假设一个错误。
  • 这不是错误,而是递归编程的本质。您可以对其进行优化,但随后该问题将再次出现在更高的数字上。这是某种家庭作业吗?那么递归在高调用上会花费很长时间这一事实将是您可以在这里学到的一课

标签: python recursion dynamic-programming


【解决方案1】:

这里有几件事需要考虑。首先是你总是检查你是否可以从 n 中减去 1。在 n 为 1 之前,这始终是正确的。因此,对于像 12 这样的数字。你最终会先拿走 1,然后再次调用函数,使用 n=11,然后 n=10,然后 n=9 等等。 ....只有在您确定了使用 -1 方法(在这种情况下 c1 将是 11)解决所需的步骤数之后,您才可以尝试 c2。

所以对于 c2,你是 12 的一半,然后调用以 -1 开头的函数,所以你最终得到 n=12、n=6、n=5、n=4...等。即使您在备忘录中有 n,您仍然会在函数调用上浪费大量时间。

相反,您可能只想尽快缩小问题空间。所以从最能减少 n 的规则开始。即除以 3,如果这不起作用则除以 2,前提是前两个都不起作用,然后减去 1。

使用此方法,您甚至不需要跟踪 n,因为 n 总是会变小,因此无需使用 memo dict 跟踪结果。

from time import time


def optimal_sequence(n):
    if n == 1:
        return 0
    elif n % 3 == 0:
        c = optimal_sequence(n // 3)
    elif n % 2 == 0:
        c = optimal_sequence(n // 2)
    else:
        c = optimal_sequence(n - 1)
    return 1 + c


n = int(input("Enter a value for N: "))
start = time()
sequence = optimal_sequence(n)
end = time()
print(f"{sequence=} took {end - start} seconds")

输入也是一个python函数,可以从你不需要使用标准输入的终端读取

输出

Enter a value for N: 96234
sequence=15 took 0.0 seconds

【讨论】:

  • 您使用的方法是贪婪的方法,并且没有给出最佳的否。操作数(n= 96234 的答案是 14 次操作)。
  • 啊,好吧,很公平。也许看看这个堆栈问题似乎是相同的场景并且有一个 python 解决方案stackoverflow.com/a/40708569/1212401
猜你喜欢
  • 2016-08-29
  • 1970-01-01
  • 1970-01-01
  • 2016-08-24
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
  • 2019-09-03
相关资源
最近更新 更多