Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用BigΘ的运行时间;符号_Python_Algorithm_Analysis - Fatal编程技术网

Python 使用BigΘ的运行时间;符号

Python 使用BigΘ的运行时间;符号,python,algorithm,analysis,Python,Algorithm,Analysis,有人能给我解释一下如何用大Θ符号来确定这些设备的运行时间吗?我读了很多东西,但仍然不知道从哪里开始 在filter中,我认为它是Θ(n^2),因为它使用谓词函数f和n个递归调用来检查大小为n的列表中的每个元素 revfilter_beta看起来非常相似,只是在过滤时反转,所以这不也是Θ(n^2)吗 revfilter_alpha会过滤一个反向,所以这不是n^2*n^2=Θ(n^4)吗 有人有什么想法吗?filter有n递归调用,但你也会在每次迭代中执行一个复制操作,这需要n,因此你最终得到了Θ(

有人能给我解释一下如何用大Θ符号来确定这些设备的运行时间吗?我读了很多东西,但仍然不知道从哪里开始

filter
中,我认为它是Θ(n^2),因为它使用谓词函数f和n个递归调用来检查大小为n的列表中的每个元素

revfilter_beta
看起来非常相似,只是在过滤时反转,所以这不也是Θ(n^2)吗

revfilter_alpha
会过滤一个反向,所以这不是n^2*n^2=Θ(n^4)吗


有人有什么想法吗?

filter
n
递归调用,但你也会在每次迭代中执行一个复制操作,这需要
n
,因此你最终得到了Θ(n^2)。如果您“正确”地实现了它,那么它应该是Θ(n)

同样适用于
my\u reverse

同样适用于
revfilter\u beta

revfilter_alpha
只做一个
filter
然后一个
reverse
,这样sΘ(n^2+n^2)=Θ(n^2)


编辑:让我们进一步了解一下
过滤器

您想要了解的是相对于输入的大小执行了多少操作
O(n)
意味着在最坏的情况下,您将按照
n
操作的顺序进行操作。我说“按顺序”是因为你可以,例如,做
O(n/2)
操作,或者
O(4n)
,但最重要的因素是
n
。也就是说,随着
n
的增长,常数因子变得越来越不重要,因此我们只看非常数因子(
n

那么,
filter
对大小
n
的列表执行多少操作

让我们从头开始。如果
n
为0-空列表怎么办?然后它将返回一个空列表。假设这是一次手术

如果
n
为1怎么办?它将检查是否应包括
lst[0]
——该检查需要多长时间才能调用
f
——然后它将复制列表的其余部分,并对该副本执行递归调用,在本例中,该副本为空列表。因此
filter(1)
需要
f+copy(0)+filter(0)
操作,其中
copy(n)
是复制列表所需的时间,而
f
是检查是否应包含元素所需的时间,假设每个元素所需的时间相同

过滤器(2)
怎么样?它将执行1次检查,然后复制列表的其余部分,并对其余部分调用
filter
f+copy(1)+filter(1)

你已经可以看到这个模式了<代码>过滤器(n)
采用
1+拷贝(n-1)+过滤器(n-1)

现在,
copy(n)
只是
n
——以这种方式对列表进行切片需要
n
操作。因此我们可以进一步简化:
filter(n)=f+n-1+filter(n-1)

现在,您可以尝试将过滤器(n-1)展开几次,看看会发生什么:

def filter(f, lst):     
    if lst == []: return []
    if f(lst[0]): return [lst[0]] + filter(f, lst[1:])
    return filter(f, lst[1:]) 

def my_reverse(lst):        # Reverse the list
    def reverse_helper(x,y):
        if x == []: return y
        return reverse_helper(x[1:], [x[0]] + y)
    return reverse_helper(lst, []) 

def revfilter_alpha(f, lst):    # Reverse and filter ...
    return my_reverse(filter(f, lst))

def revfilter_beta(f, lst): # Reverse and filter ...
    if lst == []: return []
    return revfilter_beta(f, lst[1:]) + ([lst[0]]  if f(lst[0])  else [])   
我们能概括出
x
重复吗?那
1,3,6,10,15
。。。序列是三角形数字-即,
1
1+2
1+2+3
1+2+3+4
,等等。从
1
x
的所有数字之和是
x*(x-1)/2

filter(n) = f + n-1 + filter(n-1)
          = 1 + n-1 + (f + n-2 + filter(n-2))
          = f + n-1 + f + n-2 + filter(n-2)
          = 2f + 2n-3 + filter(n-2)
          = 2f + 2n-3 + (f + n-3 + filter(n-3))
          = 3f + 3n-6 + filter(n-3)
          = 3f + 3n-6 + (f + n-4 + filter(n-4))
          = 4f + 4n-10 + filter(n-4)
          = 5f + 5n-15 + filter(n-5)
          ...
现在,什么是
x
?我们要重复多少次?好的,您可以看到当
x
=
n
时,您不再有递归-
过滤器(n-n)
=
过滤器(0)
=
1
。我们的公式是:

          = x*f + x*n - x*(x-1)/2 + filter(n-x)
我们可以进一步简化:

filter(n) = n*f + n*n - n*(n-1)/2 + 1
因此,你有它-一个相当详细的分析。那将是((1/2)n^2+(f+1/2)n+1)。。。假设
f
是不重要的(比如
f
=1),它会到达
Θ((1/2)n^2+(3/2)n+1)

现在你会注意到,如果
copy(n)
花费了一个恒定的时间量而不是一个线性的时间量(如果
copy(n)
是1而不是
n
),那么你就不会得到这个
n^2

我承认,当我最初说
Θ(n^2)
时,我并不是在脑子里想出来的。相反,我想:好吧,你有
n
递归步骤,由于
复制
,每个步骤都需要
n
时间<代码>n*n=n^2,因此
Θ(n^2)
。更准确地说,
n
在每一步都会收缩,所以实际上有
n+(n-1)+(n-2)+(n-3)+……+1
,其结果与上面的数字相同:
n*n-(1+2+3+…+n)
=
n*n-n*(n-1)/2
=
(1/2)n^2+(1/2)n
,如果我使用了上面的
0
而不是
f
,这是相同的。同样,如果您有
n
步骤,但每个步骤都是
1
而不是
n
(如果您不必复制列表),那么您就有
1+1+1+…+1
n
次,或者干脆
n


但是,这需要更多的直觉,所以我想我也会向你展示蛮力方法,你可以应用于任何事情

您的所有函数都是
O(N^2)
,因为它们每个递归步骤花费
O(N)
时间,并且在长度
N
列表上会有
N
步骤

在函数中有两个昂贵的操作(即,
O(N)
)。第一种是切片(例如
lst[1://code>)。第二种是列表连接(使用
+
运算符)

这两种方法的成本都可能比您预期的要高,这主要是因为Python的列表与其他语言中的列表数据类型不同。在引擎盖下,它们是数组,而不是链表。可以在O(1)时间内对链表执行上述操作(尽管
O(1)
切片具有破坏性)。例如,在Lisp中,您使用的算法
filter(n) = n*f + n^2 - (n^2 - n)/2 + 1
          = n*f + n^2 - n^2/2 + n/2 + 1
          = n^2 - n^2/2 + f*n + n/2 + 1
          = (1/2)n^2 + (f + 1/2)n + 1
def my_filter(f, iterable):
    for e in iterable:
        if f(e):
            yield e
def my_reversed(iterable):
    storage = list(iterable)  # consumes all the input!
    for i in range(len(storage)-1, -1, -1):
        yield storage[i]