找到Haskell功能的复杂性

发布于 2025-01-31 02:08:21 字数 241 浏览 3 评论 0原文

我如何找到复杂性(以 big-o )?

例如,

How can I find the complexity (in terms of big-O) for different Haskell functions?

For example, what is the complexity of subsequences?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

嘿看小鸭子会跑 2025-02-07 02:08:21

您只能通过查看代码来计算功能的确切复杂性。但是,您可以使用 criterion 来估算它。

例如,以下程序估算子序列的复杂性作为列表长度的函数。

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

在较新版本的Criteron中运行),

您将获得带有数据的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之外什么都不使用)。

You can only calculate the exact complexity of a function by looking at the code. However, you can estimate it using criterion.

For example, the following program estimates the complexity of subsequence as a function of the length of the list.

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)

If you compile it (with -O2!) and run it with

./Main -u report

(or

./Main --csv report

in newer versions of criteron)

you'll get a CSV file with the data (mean time, variance, and other information per run).

If you plot that data you will realise it is exponential in n as the following gnuplot session shows.

> 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'

plot

a is approximately zero, and b has almost no error. So it's a pretty sure guess that complexity is O(2^n), because e^0.71 is almost exactly 2.

Of course, this technique assumes that you're actually using everything returned by the function. If you're only accessing the first element of the returned list, the complexity will be O(1) because of lazy evaluation.

You can probably find a way to make this program independent of the function to benchmark (at least for functions that just take a list). There are also some nice Haskell libraries for plotting data, so you don't need to rely on external programs (unfortunately, as a scientist I never used anything but gnuplot).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文