Tôi hiện đang xem xét ký hiệu Big O và độ phức tạp tính toán.
Vấn đề 1.1 trong CLRS hỏi điều gì có vẻ là một câu hỏi cơ bản, đó là để có được một trực giác về mức độ phức tạp thuật toán khác nhau tăng theo kích thước của đầu vào.
Câu hỏi đặt ra:
Đối với mỗi hàm và thời gian trong bảng sau, hãy xác định kích thước lớn nhất của một vấn đề có thể giải quyết trong thời gian , giả sử rằng thuật toán để giải quyết vấn đề mất micro giây.
Các khoảng thời gian là 1 giây, 1 phút, 1 giờ, 1 ngày, 1 tháng, 1 năm, 1 thế kỷ.
Các hàm có vẻ phức tạp về thời gian thường xuất hiện trong các thuật toán, danh sách này là:
Hầu hết là các thao tác đại số khá đơn giản. Tôi đang vật lộn với hai trong số này, và cả hai vì cùng một lý do:
Nếu là thời gian tính bằng micro giây, thì hai thứ tôi đang vật lộn là
ChoTôi đã nghĩ đến việc sử dụng xấp xỉ của Stirling.
Cả hai đều yêu cầu khả năng giải quyết , với Stirling yêu cầu thao tác nhiều hơn một chút.
Câu hỏi
- Vì không thể giải được bằng các hàm cơ bản (chỉ Lambert W ), một số cách tốt để xấp xỉ gì? Hay làm thế nào để chúng ta thực hiện Lambert W?
- Làm thế nào để chúng ta giải quyết n! = c, nhất thiết phải xấp xỉ khi n phát triển lớn. Có phải đang đi đúng hướng và nếu vậy thì làm thế nào để giải quyết
Đây là một số mã python tôi đặt cùng nhau để hoàn thành bảng với đầu ra hiện tại của tôi:
EDIT: Dựa trên một vài câu trả lời, tôi đã sử dụng phương pháp tìm kiếm nhị phân (ngoại trừ lg n). Tôi đã chỉnh sửa mã dưới đây để phản ánh điều này:
+---------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
| f(n) | 1 sec | 1 min | 1 Hour | 1 Day | 1 Month | 1 Year | 1 Century |
+---------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
| lg n | 2^(1.0E+06) | 2^(6.0E+07) | 2^(3.6E+09) | 2^(8.6E+10) | 2^(2.6E+12) | 2^(3.2E+13) | 2^(3.2E+15) |
| sqrt(n) | 1.0E+12 | 3.6E+15 | 1.3E+19 | 7.5E+21 | 6.7E+24 | 9.9E+26 | 9.9E+30 |
| n | 1.0E+06 | 6.0E+07 | 3.6E+09 | 8.6E+10 | 2.6E+12 | 3.2E+13 | 3.2E+15 |
| n log n | 62746 | 2.8E+06 | 1.3E+08 | 2.8E+09 | 7.2E+10 | 8.0E+11 | 6.9E+13 |
| n^2 | 1000 | 7745 | 60000 | 293938 | 1.6E+06 | 5.6E+06 | 5.6E+07 |
| n^3 | 100 | 391 | 1532 | 4420 | 13736 | 31593 | 146645 |
| 2^n | 19 | 25 | 31 | 36 | 41 | 44 | 51 |
| n! | 9 | 11 | 12 | 13 | 15 | 16 | 17 |
+---------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
Mã Python:
import math
import decimal
from prettytable import PrettyTable
def binary_search_guess(f, t, last=1000):
for i in range(0, last):
guess = pow(2,i)
if f(guess) > t:
return binary_search_function(f, pow(2,i-1), guess, t)
return -1
def binary_search_function(f, first, last, target):
found = False
while first<=last and not found:
midpoint = (first + last)//2
if f(midpoint) <= target and f(midpoint+1) > target:
found = True
else:
if target < f(midpoint):
last = midpoint-1
else:
first = midpoint+1
best_guess = midpoint
return best_guess
def int_or_sci(x):
if x >= math.pow(10,6):
x = '%.1E' % decimal.Decimal(x)
else:
x = int(x)
return x
def input_size_calc():
#Create Pretty Table Header
tbl = PrettyTable(["f(n)", "1 sec", "1 min", "1 Hour", "1 Day", "1 Month", "1 Year", "1 Century"])
tbl.align["f(n)"] = "l" # Left align city names
tbl.padding_width = 1 # One space between column edges and contents (default)
#Each Time Interval in Microseconds
tsec = pow(10,6)
tmin = 60 * tsec
thour = 3600 * tsec
tday = 86400 * tsec
tmonth = 30 * tday
tyear = 365 * tday
tcentury = 100 * tyear
tlist = [tsec,tmin,thour,tday,tmonth,tyear,tcentury]
#print tlist
#Add rows
#lg n
f = lambda x : math.log(x,2)
fn_list = []
for t in tlist:
#This would take too long for binary search method
ans = int_or_sci(t)
fn_list.append("2^(%s)" % ans)
tbl.add_row(["lg n",fn_list[0], fn_list[1], fn_list[2], fn_list[3], fn_list[4], fn_list[5], fn_list[6]])
#sqrt(n)
f = lambda x : math.pow(x,1/2.0)
fn_list = []
for t in tlist:
fn_list.append(int_or_sci(binary_search_guess(f, t)))
tbl.add_row(["sqrt(n)",fn_list[0], fn_list[1], fn_list[2], fn_list[3], fn_list[4], fn_list[5], fn_list[6]])
#n
f = lambda x : x
fn_list = []
for t in tlist:
fn_list.append(int_or_sci(binary_search_guess(f, t)))
tbl.add_row(["n",fn_list[0], fn_list[1], fn_list[2], fn_list[3], fn_list[4], fn_list[5], fn_list[6]])
#n log n
f = lambda x : x * math.log(x,2)
fn_list = []
for t in tlist:
fn_list.append(int_or_sci(binary_search_guess(f, t)))
tbl.add_row(["n log n",fn_list[0], fn_list[1], fn_list[2], fn_list[3], fn_list[4], fn_list[5], fn_list[6]])
#n^2
f = lambda x : math.pow(x,2)
fn_list = []
for t in tlist:
fn_list.append(int_or_sci(binary_search_guess(f, t)))
tbl.add_row(["n^2",fn_list[0], fn_list[1], fn_list[2], fn_list[3], fn_list[4], fn_list[5], fn_list[6]])
#n^3
f = lambda x : math.pow(x,3)
fn_list = []
for t in tlist:
fn_list.append(int_or_sci(binary_search_guess(f, t)))
tbl.add_row(["n^3",fn_list[0], fn_list[1], fn_list[2], fn_list[3], fn_list[4], fn_list[5], fn_list[6]])
#2^n
f = lambda x : math.pow(2,x)
fn_list = []
for t in tlist:
fn_list.append(int_or_sci(binary_search_guess(f, t)))
tbl.add_row(["2^n",fn_list[0], fn_list[1], fn_list[2], fn_list[3], fn_list[4], fn_list[5], fn_list[6]])
#n!
f = lambda x : math.factorial(x)
fn_list = []
for t in tlist:
fn_list.append(int_or_sci(binary_search_guess(f, t)))
tbl.add_row(["n!",fn_list[0], fn_list[1], fn_list[2], fn_list[3], fn_list[4], fn_list[5], fn_list[6]])
print tbl
#PROGRAM BEGIN
input_size_calc()