logo

Big O apzīmējumu apmācība — Big O analīzes ceļvedis

Lielais O apzīmējums ir spēcīgs rīks, ko izmanto datorzinātnēs, lai aprakstītu algoritmu laika vai telpas sarežģītību. Tas nodrošina standartizētu veidu, kā salīdzināt dažādu algoritmu efektivitāti, ņemot vērā to sliktākā gadījuma veiktspēju. Saprašana Lielais O apzīmējums ir būtiska, lai analizētu un izstrādātu efektīvus algoritmus.

Šajā apmācībā mēs apskatīsim pamatus Lielais O apzīmējums , tā nozīmi un to, kā analizēt algoritmu sarežģītību, izmantojot Lielais O .



Satura rādītājs

Kas ir Big-O apzīmējums?

Lielais-O , ko parasti dēvē par Pasūtījums no , ir veids, kā izteikt augšējā robeža algoritma laika sarežģītību, jo tas analizē sliktākajā gadījumā algoritma situācija. Tas nodrošina an augšējā robeža par laiku, ko patērē algoritms ievades lieluma izteiksmē. Tas ir apzīmēts kā O(f(n)) , kur f(n) ir funkcija, kas attēlo darbību (soļu) skaitu, ko algoritms veic, lai atrisinātu lieluma problēmu n .



Big-O apzīmējums tiek izmantots, lai aprakstītu algoritma veiktspēju vai sarežģītību. Konkrēti, tas apraksta sliktākajā gadījumā ziņā laiks vai telpas sarežģītība.

Svarīgs punkts:

  • Lielais O apzīmējums apraksta tikai funkcijas asimptotisko uzvedību, nevis tās precīzu vērtību.
  • The Lielais O apzīmējums var izmantot, lai salīdzinātu dažādu algoritmu vai datu struktūru efektivitāti.

Big-O apzīmējuma definīcija:

Dotas divas funkcijas f(n) un g(n) , mēs tā sakām f(n) ir O(g(n)) ja pastāv konstantes c > 0 un n 0 >= 0 tāds f(n) <= c*g(n) visiem n>= n 0 .



Vienkāršāk sakot, f(n) ir O(g(n)) ja f(n) aug ne ātrāk kā c*g(n) visiem n>= n0kur c un n0ir konstantes.

Kāpēc lielais O apzīmējums ir svarīgs?

Lielais O apzīmējums ir matemātisks apzīmējums, ko izmanto, lai aprakstītu algoritma sliktākā gadījuma laika sarežģītību vai efektivitāti vai datu struktūras sliktākā gadījuma telpas sarežģītību. Tas nodrošina veidu, kā salīdzināt dažādu algoritmu un datu struktūru veiktspēju un paredzēt, kā tie darbosies, palielinoties ievades lielumam.

Lielais O apzīmējums ir svarīgs vairāku iemeslu dēļ:

  • Lielais O apzīmējums ir svarīgs, jo tas palīdz analizēt algoritmu efektivitāti.
  • Tas nodrošina veidu, kā aprakstīt, kā izpildlaiks vai telpas prasības algoritms pieaugs, palielinoties ievades lielumam.
  • Ļauj programmētājiem salīdzināt dažādus algoritmus un izvēlēties visefektīvāko konkrētai problēmai.
  • Palīdz izprast algoritmu mērogojamību un paredzēt, kā tie darbosies, palielinoties ievades lielumam.
  • Ļauj izstrādātājiem optimizēt kodu un uzlabot vispārējo veiktspēju.

Lielā O apzīmējuma īpašības:

Tālāk ir norādītas dažas svarīgas Big O apzīmējuma īpašības:

1. Refleksivitāte:

Jebkurai funkcijai f(n) f(n) = O(f(n)).

satur apakšvirkni java

Piemērs:

f(n) = n2, tad f(n) = O(n2).

2. Transitivitāte:

Ja f(n) = O(g(n)) un g(n) = O(h(n)), tad f(n) = O(h(n)).

Piemērs:

f(n) = n3, g(n) = n2, h(n) = n4. Tad f(n) = O(g(n)) un g(n) = O(h(n)). Tāpēc f(n) = O(h(n)).

3. Pastāvīgais faktors:

Jebkurai konstantei c> 0 un funkcijām f(n) un g(n), ja f(n) = O(g(n)), tad cf(n) = O(g(n)).

Piemērs:

f(n) = n, g(n) = n2. Tad f(n) = O(g(n)). Tāpēc 2f(n) = O(g(n)).

4. Summas noteikums:

Ja f(n) = O(g(n)) un h(n) = O(g(n)), tad f(n) + h(n) = O(g(n)).

Piemērs:

f(n) = n2, g(n) = n3, h(n) = n4. Tad f(n) = O(g(n)) un h(n) = O(g(n)). Tāpēc f(n) + h(n) = O(g(n)).

5. Produkta noteikums:

Ja f(n) = O(g(n)) un h(n) = O(k(n)), tad f(n) * h(n) = O(g(n) * k(n)) .

Piemērs:

f(n) = n, g(n) = n2, h(n) = n3, k(n) = n4. Tad f(n) = O(g(n)) un h(n) = O(k(n)). Tāpēc f(n) * h(n) = O(g(n) * k(n)) = O(n)5).

6. Sastāva noteikums:

Ja f(n) = O(g(n)) un g(n) = O(h(n)), tad f(g(n)) = O(h(n)).

Piemērs:

f(n) = n2, g(n) = n, h(n) = n3. Tad f(n) = O(g(n)) un g(n) = O(h(n)). Tāpēc f(g(n)) = O(h(n)) = O(n3).

Parastie lielo O apzīmējumi:

Big-O apzīmējums ir veids, kā izmērīt algoritma laika un telpas sarežģītību. Tas apraksta sarežģītības augšējo robežu sliktākajā gadījumā. Apskatīsim dažādus laika sarežģītības veidus:

1. Lineārā laika sarežģītība: liela O(n) sarežģītība

Lineārā laika sarežģītība nozīmē, ka algoritma darbības laiks pieaug lineāri līdz ar ievades lielumu.

Piemēram, apsveriet algoritmu, kas šķērso masīvu, lai atrastu konkrētu elementu :

Koda fragments
bool findElement(int arr[], int n, int key) {  for (int i = 0; i < n; i++) {  if (arr[i] == key) {  return true;  }  }  return false; }>

2. Logaritmiskā laika sarežģītība: liela O(log n) sarežģītība

Logaritmiskā laika sarežģītība nozīmē, ka algoritma darbības laiks ir proporcionāls ievades lieluma logaritmam.

Piemēram, a binārās meklēšanas algoritms ir logaritmiska laika sarežģītība:

Koda fragments
int binarySearch(int arr[], int l, int r, int x) {  if (r>= l) { int mid = l + (r - l) / 2;  if (arr[mid] == x) return mid;  if (arr[mid]> x) return binarySearch(arr, l, mid - 1, x);  return binarySearch(arr, mid + 1, r, x);  } atgriešanās -1; }>

3. Kvadrātiskā laika sarežģītība: liels O(n2) Sarežģītība

Kvadrātiskā laika sarežģītība nozīmē, ka algoritma darbības laiks ir proporcionāls ievades lieluma kvadrātam.

Piemēram, vienkāršs burbuļu kārtošanas algoritms ir kvadrātiskā laika sarežģītība:

Koda fragments
void bubbleSort(int arr[], int n) {  for (int i = 0; i < n - 1; i++) {  for (int j = 0; j < n - i - 1; j++) {  if (arr[j]>arr[j + 1]) { mijmaiņas (&arr[j], &arr[j + 1]);  } } } }>

4. Kubiskā laika sarežģītība: liels O(n3) Sarežģītība

Kubiskā laika sarežģītība nozīmē, ka algoritma darbības laiks ir proporcionāls ievades lieluma kubam.

Piemēram, naivs matricas reizināšanas algoritms ir kubiskā laika sarežģītība:

Koda fragments
void multiply(int mat1[][N], int mat2[][N], int res[][N]) {  for (int i = 0; i < N; i++) {  for (int j = 0; j < N; j++) {  res[i][j] = 0;  for (int k = 0; k < N; k++)  res[i][j] += mat1[i][k] * mat2[k][j];  }  } }>

5. Polinoma laika sarežģītība: liels O(nk) Sarežģītība

Polinoma laika sarežģītība attiecas uz algoritma laika sarežģītību, ko var izteikt kā ievades lieluma polinoma funkciju n . Lielajā O Apzīmējums, algoritmam ir polinoma laika sarežģītība, ja tā laika sarežģītība ir tāda O(n k ) , kur k ir konstante un apzīmē polinoma pakāpi.

Algoritmi ar polinoma laika sarežģītību parasti tiek uzskatīti par efektīviem, jo ​​darbības laiks pieaug saprātīgā ātrumā, palielinoties ievades lielumam. Parastie algoritmu piemēri ar polinoma laika sarežģītību ietver lineārā laika sarežģītība O(n) , kvadrātiskā laika sarežģītība O(n 2 ) , un kubiskā laika sarežģītība O(n 3 ) .

6. Eksponenciālā laika sarežģītība: liela O(2n) Sarežģītība

Eksponenciālā laika sarežģītība nozīmē, ka algoritma darbības laiks dubultojas ar katru pievienošanu ievades datu kopai.

Piemēram, problēma ģenerējot visas kopas apakškopas ir eksponenciālas laika sarežģītības pakāpe:

Koda fragments
void generateSubsets(int arr[], int n) {  for (int i = 0; i < (1 << n); i++) {  for (int j = 0; j < n; j++) {  if (i & (1 << j)) {  cout << arr[j] << ' ';  }  }  cout << endl;  } }>

Faktoriāla laika sarežģītība: liela O(n!) sarežģītība

Faktoriālā laika sarežģītība nozīmē, ka algoritma darbības laiks palielinās atkarībā no ievades lieluma. To bieži var redzēt algoritmos, kas ģenerē visas datu kopas permutācijas.

Šis ir faktoriālā laika sarežģītības algoritma piemērs, kas ģenerē visas masīva permutācijas:

Koda fragments
void permute(int* a, int l, int r) {  if (l == r) {  for (int i = 0; i <= r; i++) {  cout << a[i] << ' ';  }  cout << endl;  }  else {  for (int i = l; i <= r; i++) {  swap(a[l], a[i]);  permute(a, l + 1, r);  swap(a[l], a[i]); // backtrack  }  } }>

Ja mēs attēlosim visbiežāk sastopamos Big O apzīmējumu piemērus, mēs iegūtu šādu grafiku:

Asimtotiskā analīze

Kā noteikt lielo O apzīmējumu?

Lielais O apzīmējums ir matemātisks apzīmējums, ko izmanto, lai aprakstītu asimptotiska uzvedība funkcijas, jo tās ievade kļūst bezgalīgi liela. Tas nodrošina veidu, kā raksturot algoritmu un datu struktūru efektivitāti.

Darbības, lai noteiktu lielo O apzīmējumu:

1. Identificējiet dominējošo terminu:

  • Izpētiet funkciju un identificējiet terminu ar visaugstāko pieauguma pakāpi, palielinoties ievades lielumam.
  • Ignorējiet visus nemainīgos faktorus vai zemākas kārtas vārdus.

2. Nosakiet izaugsmes secību:

  • Dominējošā vārda pieauguma secība nosaka Big O apzīmējumu.

3. Uzrakstiet lielo O apzīmējumu:

  • Lielo O apzīmējumu raksta kā O(f(n)), kur f(n) apzīmē dominējošo vārdu.
  • Piemēram, ja dominējošais vārds ir n^2, lielais O apzīmējums būtu O(n^2).

4. Vienkāršojiet apzīmējumu (neobligāti):

  • Dažos gadījumos, Big O zīmols n var vienkāršot, noņemot nemainīgos faktorus vai izmantojot kodolīgāku apzīmējumu.
  • Piemēram, O(2n) var vienkāršot līdz O(n).

Piemērs:

Funkcija: f(n) = 3n3+ 2n2+ 5n + 1

  1. Dominējošais termins: 3n3
  2. Izaugsmes secība: kubiskais (n3)
  3. Lielais O apzīmējums: O (n3)
  4. Vienkāršots apzīmējums: O(n3)

Izpildlaika analīzes matemātiskie piemēri:

Zemāk redzamā tabula ilustrē dažādu algoritmu secību izpildlaika analīzi, palielinoties ievades lielumam (n).

nžurnāls(n)nn * žurnāls(n)n^22^nn!
101101010010243628800
divdesmit2996divdesmit59.940010485762.432902e+1818

Izpildlaika analīzes algoritmiskie piemēri:

Zemāk esošajā tabulā ir klasificēti algoritmi, pamatojoties uz to izpildlaika sarežģītību, un sniegti piemēri katram veidam.

TipsApzīmējumsAlgoritmu piemēri
LogaritmisksO(log n)Binārā meklēšana
LineārsO(n)Lineārā meklēšana
SuperlineārsO(n log n)Kaudzes kārtošana, sapludināšanas kārtošana
PolinomsO(n^c)Štrasena matricas reizināšana, burbuļu kārtošana, atlases kārtošana, ievietošanas kārtošana, spaiņu kārtošana
EksponenciālsO(c^n)Hanojas tornis
FaktoriālsO (n!)Noteicošā nepilngadīgo paplašināšanās, brutāla spēka meklēšanas algoritms ceļojošā pārdevēja problēmai

Algoritmu klases ar operāciju skaitu un izpildes laiku:

Tālāk ir norādītas algoritmu klases un to izpildes laiki datorā, kas tiek izpildīts 1 miljons darbību sekundē (1 s = 10 6 μs = 10 3 msec) :

Lielās O notācijas klases

f(n)

Lielā O analīze (operāciju skaits), ja n = 10

Izpildes laiks (1 instrukcija/μs)

nemainīgs

O(1)

1

1 μsek

logaritmisks

multipleksors

O(pieteikties)

3.32

3 μs

lineārs

O(n)

10

10 μs

O(nelogn)

O(nelogn)

33.2

33 μs

kvadrātveida

O(n2)

102

100 μs

kub

O(n3)

103

1 ms

eksponenciāls

O(2n)

1024

10 ms

faktoriāls

O (n!)

Word ātrās piekļuves rīkjosla

10!

3,6288 sek

Lielā O apzīmējuma, lielā Ω (Omega) apzīmējuma un lielā θ (teta) apzīmējuma salīdzinājums:

Tālāk ir sniegta tabula, kurā salīdzināts Big O apzīmējums, Ω (Omega) un θ (Theta) apzīmējums:

ApzīmējumsDefinīcijaPaskaidrojums
Lielais O (O)f(n) ≤ C * g(n) visiem n ≥ n0Apraksta algoritma darbības laika augšējo robežu sliktākajā gadījumā .
Ω (Omega)f(n) ≥ C * g(n) visiem n ≥ n0Apraksta algoritma darbības laika apakšējo robežu labākais gadījums .
θ (teta)C1* g(n) ≤ f(n) ≤ C2* g(n), ja n ≥ n0Apraksta gan algoritma augšējo, gan apakšējo robežu darbības laiks .

Katrā apzīmējumā:

  • f(n) apzīmē analizējamo funkciju, parasti algoritma laika sarežģītību.
  • g(n) apzīmē noteiktu funkciju, kas ierobežo f(n) .
  • C, C1, un C2 ir konstantes.
  • n 0 ir minimālais ievades lielums, pēc kura pastāv nevienlīdzība.

Šie apzīmējumi tiek izmantoti, lai analizētu algoritmus, pamatojoties uz tiem sliktākais gadījums (Big O) , labākais gadījums (Ω) , un vidējais gadījums (θ) scenāriji.

Bieži uzdotie jautājumi par lielo O apzīmējumu:

1. jautājums. Kas ir lielais O apzīmējums?

Atbilde: Lielais O apzīmējums ir matemātisks apzīmējums, ko izmanto, lai aprakstītu algoritma laika sarežģītības augšējo robežu, ņemot vērā to, kā tas pieaug attiecībā pret ievades lielumu.

2. jautājums. Kāpēc lielais O apzīmējums ir svarīgs?

Atbilde: Tas palīdz mums analizēt un salīdzināt algoritmu efektivitāti, koncentrējoties uz sliktāko scenāriju un izprotot, kā to veiktspēja mainās atkarībā no ievades lieluma.

3. jautājums. Kā tiek aprēķināts lielais O apzīmējums?

Atbilde: Lielo O apzīmējumu nosaka, identificējot dominējošo darbību algoritmā un izsakot tās laika sarežģītību n izteiksmē, kur n apzīmē ievades lielumu.

4. jautājums. Ko O(1) nozīmē lielajā O apzīmējumā?

Atbilde: O (1) apzīmē pastāvīgu laika sarežģītību, norādot, ka algoritma izpildes laiks nemainās neatkarīgi no ievades lieluma.

5. jautājums. Kāda ir dažādu lielo O sarežģītību, piemēram, O(log n) vai O(n^2) nozīme?

Atbilde: Dažādas sarežģītības, piemēram, O(log n) vai O(n^2), atspoguļo algoritma veiktspējas mērogošanu, palielinoties ievades lielumam, sniedzot ieskatu tā efektivitātē un mērogojamībā.

6. jautājums. Vai lielo O apzīmējumu var attiecināt arī uz telpas sarežģītību?

Atbilde: Jā, Big O notation var izmantot arī, lai analizētu un aprakstītu algoritma telpas sarežģītību, norādot, cik daudz atmiņas tam nepieciešams attiecībā pret ievades lielumu.

Saistīts raksts: