Ich beschäftige mich derzeit mit der Big O-Notation und der Komplexität der Berechnungen.
Problem 1.1 in CLRS stellt die Frage, was eine grundlegende Frage zu sein scheint, nämlich eine Vorstellung davon zu bekommen, wie unterschiedliche algorithmische Komplexitäten mit der Größe der Eingabe wachsen.
Die Frage lautet:
Bestimmen Sie für jede Funktion und Zeit in der folgenden Tabelle die größte Größe eines Problems, die in der Zeit gelöst werden kann , unter der Annahme, dass der Algorithmus zur Lösung des Problems Mikrosekunden benötigt.
Die Zeiträume sind 1 Sekunde, 1 Minute, 1 Stunde, 1 Tag, 1 Monat, 1 Jahr, 1 Jahrhundert.
Die Funktionen sind scheinbar häufige Zeitkomplexitäten, die in Algorithmen häufig auftreten. Die Liste lautet:
Die meisten sind ziemlich einfache algebraische Manipulationen. Ich habe mit zwei davon zu kämpfen, und beide aus demselben Grund:
Wenn die Zeit in Mikrosekunden ist, sind die beiden, mit denen ich zu kämpfen habe,
FürIch dachte daran, Stirlings Approximation zu verwenden.
Beide erfordern die Fähigkeit, zu lösen, Stirling etwas mehr Manipulation erfordert.
Fragen
- Da nicht mit Elementarfunktionen lösbar ist (nur Lambert W ), was sind einige gute Möglichkeiten, um zu approximieren ? Oder wie implementieren wir Lambert W?
- Wie lösen wir n! = c, notwendigerweise ungefähr, wenn n groß wird. Ist Stirling der richtige Weg und wenn ja, wie löse ich
Hier ist ein Python-Code, den ich zusammengestellt habe, um die Tabelle mit meiner aktuellen Ausgabe zu vervollständigen:
BEARBEITEN: Basierend auf einigen Antworten habe ich eine binäre Suchmethode verwendet (außer lg n). Ich habe den folgenden Code bearbeitet, um dies widerzuspiegeln:
+---------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+
| 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-Code:
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()
quelle
Antworten:
Die ungefähre Umkehrung von ist . In der Tat haben wir für diesen Wert von Diese Annäherung ist normalerweise gut genug.c=nlogn n=c/logc n
quelle
Sie müssen nichts annähern, um die Übung zu lösen. Alle Funktionen, die Sie erhalten, sind monoton, sodass Sie nur die binäre Suche verwenden können. Das heißt, um für zu lösen , raten Sie einfach bis Sie das erste , das . Führen Sie dann eine normale binäre Suche zwischen und . Wenn die Lösung , werden ungefähr Auswertungen von .f(n)=c n n=1,2,4,8,… k 2klog2k>c 2k−1 2k x 2logx f
quelle