【问题标题】:Finding the complexity of Haskell functions找出 Haskell 函数的复杂性
【发布时间】:2013-12-02 17:48:18
【问题描述】:

如何找到不同 Haskell 函数的复杂性(以big-O 表示)?

比如subsequences的复杂度是多少?

【问题讨论】:

  • 没有确定函数复杂度的好方法,您必须查看源代码并了解生成它的算法。你总是可以做一些实验来确定它的数值,但这也并不总是那么简单。
  • 一些软件包记录了它们的复杂性。例如,containers 在这方面做得很好。
  • 另外,很多时候复杂性并不是直接记录下来的。例如,sortData.List 的复杂度类似于 O(n*log k),其中 n 是列表的长度,k 是您从结果中检查的元素数。
  • 如前所述,在惰性上下文中计算时间复杂度可能很棘手。 Okazaki 的book on purely functional datastructures 涵盖了许多此类主题,包括摊销。买不到书也可以免费查看他的博士论文。
  • 很大程度上取决于函数的使用方式。例如。 head $ subsequences [1..n] 是 O(1)。

标签: haskell complexity-theory


【解决方案1】:

您只能通过查看代码来计算函数的确切复杂度。但是,您可以使用criterion 进行估算。

例如,以下程序将subsequence 的复杂度估计为列表长度的函数。

module Main where

import Criterion (bench, nf)
import Criterion.Main (defaultMain)
import Data.List (subsequences)
import Control.DeepSeq (deepseq)

main = defaultMain (map createBenchmark [0, 2 .. 24])
    where
        createBenchmark n =
            let
                xs = replicate n 'x'
            in
                xs `deepseq` (bench (show n) $ nf subsequences xs)

如果你编译它(使用-O2!)并运行它

./Main -u report

(或

./Main --csv report

在较新版本的标准中)

您将获得一个包含数据(平均时间、方差和每次运行的其他信息)的 CSV 文件。

如果您绘制该数据,您会发现它在 n 中呈指数增长,如下面的 gnuplot 会话所示。

> f(x) = a * exp(b * x)
> fit f(x) 'report' using ($0 * 2):2 every ::2 via a,b
...

Final set of parameters            Asymptotic Standard Error
=======================            ==========================

a               = 1.7153e-07       +/- 5.441e-09    (3.172%)
b               = 0.711104         +/- 0.001438     (0.2023%)


correlation matrix of the fit parameters:

               a      b      
a               1.000 
b              -1.000  1.000
> set log y
> set xlabel 'n'
> set ylabel 'mean time [s]'
> plot 'report' using ($0 * 2):2 every ::2 with lp title 'data', f(x) title 'fit'

a 近似为零,b 几乎没有错误。所以可以肯定地猜测复杂度是 O(2^n),因为 e^0.71 几乎正好是 2。

当然,这种技术假设您实际上使用了函数返回的所有内容。如果您只访问返回列表的第一个元素,由于延迟评估,复杂度将为 O(1)。

您可能会找到一种方法使该程序独立于要进行基准测试的函数(至少对于只获取列表的函数)。还有一些不错的 Haskell 库用于绘制数据,因此您无需依赖外部程序(不幸的是,作为一名科学家,我除了 gnuplot 从未使用过任何东西)。

【讨论】:

  • LogPlot 在这里可能很棒,因为指数定律。在幂律的情况下,对数图。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-25
  • 2014-11-12
  • 1970-01-01
相关资源
最近更新 更多