如何通过递归算法冒出“不可能”的值?

时间:2013-03-06 17:19:41

标签: recursion dynamic-programming

我有一个特殊情况下的递归算法,例如路径算法,如果路径好,我想在距离上加1,但如果遇到死路则返回-1。当用一堆递归调用解决最大化问题时,这是有问题的。

是否有更好的方法来编码以下内容:

def rec(n):
  if n == 1:
    return -1
  if n == 0:
    return 1
  val = rec(n - 2)
  if val == -1:
    return -1
  else:
    return val + 1

因此,rec(4) = 2rec(3) = -1

2 个答案:

答案 0 :(得分:2)

在Python中,不是真的。你可以通过返回None而不是-1来使Python更清晰;这样做的好处是错误地添加到无效值会引发异常。

具有更严格的类型系统和“可能”或可选值的良好概念的语言使其变得简单。说,哈斯克尔:

rec 1 = Nothing
rec 0 = Just 1
rec n = map ((+) 1) $ rec (n - 2)

map调用意味着它将添加框中的任何内容(如果它是Just x),并返回无效值(Nothing)不变。当然,您可以设计自己的更复杂的类型,允许多个错误条件或任何其他,并仍然获得类似的简单结果。在OCaml,F#,Standard ML和Scala中,这几乎一样容易。

您可以通过定义辅助函数在Python中使用None来模拟此方法:

def mapMaybe(obj, f):
    if obj is None:
        return None
    else:
        return f(obj)

然后你可以这样做:

return mapMaybe(val, lambda x: x + 1)

但我不知道我真的建议这样做。

模拟Scala的书中的技巧,也可以将所有这些包装在生成器理解中(未经测试):

def maybe(x):
    if x is not None:
        yield x

def firstMaybe(it):
    try:
        return it.next()
    except StopIteration:
        return None

然后:

return firstMaybe(x + 1 for x in maybe(val))

但那真的是非标准的,非惯用的Python。

答案 1 :(得分:1)

一种有用的技术是选择“无可用解决方案”值,以便将其处理为表示解决方案仍然会产生“无解决方案”值。例如,如果低数字代表最佳解决方案,则可以选择比任何有意义的有效解决方案更大的值。如果使用整数类型,则必须确保“无可用解决方案”值足够小以至于对其进行操作,就好像它是有效的解决方案一样不会导致数值溢出[例如如果递归调用总是假设来自某个位置的解决方案的成本将比递归调用生成的解决方案的成本大一个,那么使用大于999,999,999的值来表示“无解决方案可用”应该起作用;但是,如果代码可能将解决方案的成本视为两个其他解决方案的总和,则可能需要选择较小的值]。或者,可以使用浮点类型,因为“正无穷大”的值将比任何其他值更大,并且向其添加任何正数或有限数量都不会改变它。