【问题标题】:Time Complexity of Text Justification with Dynamic Programming动态规划文本对齐的时间复杂度
【发布时间】:2016-07-13 10:20:27
【问题描述】:

我一直在处理dynamic programming problem involving the justification of text。我相信我已经找到了一个可行的解决方案,但我对该算法的运行时间感到困惑。

到目前为止,我所做的研究将该问题的动态编程解决方案描述为 O(N^2),其中 N 作为正在被处理的文本的长度有道理。对我来说,这感觉不正确:我可以看到必须进行 O(N) 次调用,因为要检查 N 个后缀,但是,对于任何给定的前缀,我们永远不会考虑将换行符(或“split_point”)放在最大行之外长度L。因此,对于任何给定的文本,最多有 L 个位置来放置分割点(这是​​假设最坏的情况:每个单词正好是一个字符长)。由于这个实现,这个算法不是更准确地描述为 O(LN) 吗?

@memoize
def justify(text, line_length):

    # If the text is less than the line length, do not split
    if len(' '.join(text)) < line_length:
        return [], math.pow(line_length - len(' '.join(text)), 3)

    best_cost, best_splits = sys.maxsize, []

    # Iterate over text and consider putting split between each word
    for split_point in range(1, len(text)):
        length = len(' '.join(text[:split_point]))

        # This split exceeded maximum line length: all future split points unacceptable
        if length > line_length:
            break

        # Recursively compute the best split points of text after this point
        future_splits, future_cost = justify(text[split_point:], line_length)
        cost = math.pow(line_length - length, 3) + future_cost

        if cost < best_cost:
            best_cost = cost
            best_splits = [split_point] + [split_point + n for n in future_splits]

    return best_splits, best_cost

提前感谢您的帮助, 伊森

【问题讨论】:

  • 这里的规范 DP 算法检查所有开始和结束位置的惩罚(或成本)。 ie) cost[i][j] = pinchForWordsOnLineBetween(i,j) 对于所有有效位置 i,j 即 N^2

标签: algorithm time-complexity big-o dynamic-programming


【解决方案1】:

首先,您的实现与您想要的理论效率相去甚远。您在调用中记住了一个长度为N 的字符串,这意味着查找数据的缓存副本可能是O(N)。现在开始进行多个缓存调用,但您已经超出了复杂性预算。

这可以通过将文本移出函数调用并传递起始位置的索引和长度L 来解决。您还在循环内进行连接,即O(L) 操作。稍加小心,您可以改为使用O(1) 操作。

完成后,您将执行O(N*L) 操作。正是因为你想的原因。

【讨论】:

  • 记忆优化的好主意
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-01
相关资源
最近更新 更多