算法分析筆記

定義


定義:python

  1. 若存在正常數 c 和 n<sub>0</sub> 使得當 N ≥ n<sub>0</sub> 時 T(N) ≤ cf(N),則記爲 T(N) = O(f(N))
  2. 若存在正常數 c 和 n<sub>0</sub> 使得當 N ≥ n<sub>0</sub> 時 T(N) ≥ cf(N),則記爲 T(N) = Ω(f(N))
  3. T(N) = θ(h(N)) 當且僅當 T(N) = O(h(N))T(N) = Ω(h(N))
  4. T(N) = O(p(N))T(N) != θ(p(N)), 則 T(N) = o(p(N))

法則:算法

  1. 若 T<sub>1</sub>(N) = O(f(N)) 且 T<sub>2</sub>(N)=O(g(N)),則:dom

    a. T<sub>1</sub>(N) + T<sub>2</sub>(N) = max(O(f(N)), O(g(N)))
    
    b. T<sub>1</sub>(N) * T<sub>2</sub>(N) = O(f(N) * g(N))
  2. 若 T(N) 是一個 k 次多項式,則 T(N) = Θ(N<sup>k</sup>)函數

  3. 對任意常數 k,log<sup>k</sup>N = O(N)測試

注意:優化

  1. 不要將常數或低階項放入 O() ,在 O 分析中,低階項和常數通常能夠忽略。
  2. 總可以經過計算 n→∞ 時 f(N)/g(N) 的極限來肯定這兩個函數的相對增加率。

最大子序列問題


能夠分段讀入數據並處理問題的算法稱爲 online algrithm,與之相對,在運算開始時就須要讀入所有數據作運算的算法稱爲 offline algrithm。僅須要常量內存空間並以線性時間運行的算法幾乎是完美的算法。以下例最大子序列問題:ui

lang:python
data = list(range(-10, 10))
random.shuffle(data)

# 算法
def foo(data):
    this_sum = max_sum = 0
    for i in data:
        this_sum += i
        if this_sum < 0:
            this_sum = 0
        elif this_sum > max_sum:
            max_sum = this_sum
    return max_sum

對數


若是一個算法用常數時間(O(1) )將問題的大小削減爲其一部分(一般是 1/2),那麼該算法就是 O(logN)this

若是一個算法能夠用常數時間把問題減少一個常數,那麼他就是 O(N) 的。code

對數複雜度的一個典型例子是:二分法查找 (binary search)排序

def bin_search(numbers, x):
	"""假設 numbers 已排序"""
	start = 0
	end = len(numbers) - 1
	
	while start < end:
		middle = (start + end) / 2
		if numbers[middle] < x:
			start = middle + 1
		elif numbers[middle] > x:
			end = middle - 1
		else:
			return middle
	return -1

歐幾里得算法


計算最大公因數:

def gcd(a, b):
	while b > 0:
		a = a % b
		a, b = b, a
	return a

定理:

若 M > N, 則 M mod N < M/2

推得:gcd 函數的時間複雜度是 O(log N) 的

冪運算


優化算法的一個原則是:不要作重複的運算

所以對於冪運算 x<sup>n</sup>,相較於進行 n-1 次乘法,下面的算法效率更高:

def pow(x, n):
	if n == 0:
		return 1
	if n == 1:
		return n
	if n % 2 == 0:
		return pow(x * x, n / 2)
	else:
		return x * pow(x * x, (n-1) / 2)

檢驗算法時間


python 中能夠用 timeit.timeit 函數方便的檢驗算法時間

timeit(stmt='pass', setup='pass', timer=<built-in function perf_counter>,
		number=1000000, globals=None)

其中:

* stmt statement 是一個字符串表達式
* setup 是一個執行前置語句,如 import
* globals 是一個字典,存放你要使用的全局變量

如,咱們要測試 gcd 函數,則

import timeit
timeit.timeit('gcd(15, 234)', globals={'gcd': gcd})
相關文章
相關標籤/搜索