私は現在Big O表記法と計算の複雑さを調べています。
CLRSの問題1.1は、基本的な質問のように聞こえます。これは、入力のサイズとともにさまざまなアルゴリズムの複雑さがどのように成長するかについての直感を得ることです。
質問は尋ねます:
次の表の各関数と時間について、問題を解決するアルゴリズムにマイクロ秒かかると仮定して、時間で解決できる問題の最大サイズを決定します。
期間は、1秒、1分、1時間、1日、1か月、1年、1世紀です。
関数は、アルゴリズムで頻繁に発生する一般的な時間の複雑さであり、リストは次のとおりです。
ほとんどはかなり単純な代数的操作です。私はこれらの2つ、そして同じ理由で両方に苦労しています:
がマイクロ秒の時間である場合、私が苦労している2つは
以下のためスターリングの近似を使用することを考えました。
これらはどちらもを解く能力を必要とし、スターリングはもう少し操作が必要です。
ご質問
- 初等関数(のみ使用して解くことができないですランバートWを)、おおよそのにはいくつかの良い方法何?または、ランバートWをどのように実装しますか?
- どのようにnを解くのですか?= c、nが大きくなると、ほぼ必ず。スターリングは正しい道であり、そうであればを解決する方法
以下は、現在の出力でテーブルを完成させるためにまとめたpythonコードです。
編集:いくつかの回答に基づいて、私は二分探索法を使用しました(lg nを除く)。これを反映するために、以下のコードを編集しました。
+---------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
| 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 |
+---------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
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()
3
の値に対してバイナリ検索を実行するか、テイラー級数を使用することにより、を概算できます。階乗関数を連続的に、ガンマ関数に拡張でき、おそらくその逆に関する情報を見つけることができますが、スターリング近似を使用したアプローチも同様にうまくいきます。
—
トムファンデルザンデン
このPDFを確認してください:cs-people.bu.edu/lapets/resource/nlogn.pdf
—
Sagnik
@TomvanderZanden Forgetバイナリ検索を行うだけで質問全体を概算できます!
—
David Richerby、2015
分数に注意してください... nが大きい場合は3桁の有効数字を使用するのが妥当ですが、nが小さい場合は、最も近い整数に切り捨ててください。
—
Ben Voigt 2015
@DavidRicherbyこれについて詳しく教えてください。
—
stats_novice_123 2015