O(N^2) lepszyod O(N)

K1
  • Rejestracja:ponad 6 lat
  • Ostatnio:ponad 5 lat
  • Postów:32
0

Podaj trzy przypadki kiedy algorytm o złożoności O(N^2) jest lepszym wyborem od algorytmu o złożoności O(N).

Pipes
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 3 lata
  • Postów:459
2
  1. Kartkówka z programowania w liceum
  2. w.w. w technikum
  3. kolokwium na pierwszym roku studiów
lion137
  • Rejestracja:około 8 lat
  • Ostatnio:około 6 godzin
  • Postów:4882
10

Np.: n * n jest lepszy od n + 1000000000000 do pewnego n.


Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
10
  1. Złożoność pamięciowa. Można sortować liczby w O(n) ale wymaga to O(k) pamięci gdzie k to maksymalna liczba. Dla 64bitowych intów nie starczy pamieci :)
  2. Stałe ukryte w notacji O, jw. sortowanie przez zliczanie niby jest O(n) ale w praktyce O(n*k), więc jak liczb jest mało a zakres liczb duzy to będzie to działać wolniej
  3. Poziom skomplikowania algorytmu? Kontrowersyjne, ale w praktyce kod musi być zrozumiały :) Skomplikowany algorytm w miejscu które nie wymaga optymalizacji czasowej, może zwyczajnie nie mieć sensu, bo utrzymanie będzie kosztowne a zysk żaden.

"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
lion137
  • Rejestracja:około 8 lat
  • Ostatnio:około 6 godzin
  • Postów:4882
0

Dodam jeszcze (pozostaje w mocy, to co napisał @Shalom), że zdanie z mojego poprzedniego postu mozna odwrócić, tzn., algorytmy są asymptotycznie lepsze, od pewnego n, co nie znaczy, że są zawsze lepsze. Ekstremalny przypadek: P = NP, ale algorytm wielomianowy jest z jakąś absurdalnie wielką stałą: n + 1000^1000(!). Wszelkie medale i wieczna chwała gwarantowane, ale praktycznie takie odkrycie zmieni nic.
Let's get real, algorytmy sortowania w bibliotekach standartowych zmieniają między implementacjami, zależnie od wielkości i rodzaju danych; algorytmy mnożenia również - np., przez dużą ilość stałych operacji, algorytm mnożenia Shonhage - Strassen, jest efektywny dopiero dla wielkich liczb.


edytowany 2x, ostatnio: lion137
Satanistyczny Awatar
  • Rejestracja:ponad 6 lat
  • Ostatnio:2 miesiące
  • Postów:688
1
  1. Kiedy jeden jest zaimplementowany baremetal w asm a drugi w Javie.
  2. Kiedy chodzi nam o ogrzanie pomieszczenia za pomocą procesora.
  3. Kiedy dłuższy czas wykonywania zapewnia nam więcej czasu na opier*alanie się w pracy
edytowany 2x, ostatnio: Satanistyczny Awatar
Shalom
1. ktoś nie umie w JITa chyba...
Satanistyczny Awatar
@Shalom Pfffffffff jasne
hauleth
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:4 dni
5

Tak jak powiedział @Shalom czas wykonania to nie jedyny aspekt algorytmu, z innych (poza wymienioną złożonością pamięciową):

  • cache friendliness - nawet jeśli notacja O jest lepsza dla algorytmu X, to czasem siłą zrobisz więcej niż fancy algorytmami (jeśli masz dużo siły)
  • algorytm jest on-line czy off-line?
  • stabilność algorytmu (czy wynik zależy od kolejności danych na wejściu)
  • możliwość zrównoleglenia algorytmu oraz jaki procent pracy można zrównoleglić
  • jaka jest struktura danych (ex. sortowanie niemutowalnych list przy użyciu quicksorta to średniawy pomysł)

edytowany 2x, ostatnio: hauleth
Zobacz pozostały 1 komentarz
hauleth
Racja, poprawiam link.
Satanistyczny Awatar
Jak już jesteśmy przy tym - nie obiło wam się może o gałki oczne porównanie architektur i efektywności algorytmów sortowania na nich?
hauleth
@Satanistyczny Awatar: ja znam 2 sekwencyjne struktury danych: listy i tablice/wektory, wiec jeśli masz random access to qsort (jeśli stabilność nie jest wymagana) lub co chcesz, jeśli ma być stabilnie, natomiast listy to merge sort.
Satanistyczny Awatar
ta, acz mi chodziło o np. architektury typu RISC - takie a takie algo działa na nim tak, a tak, a CISC - jeszcze inaczej, a na jakichś egzotykach "tak, a tak". Nie dopisałem "procesora". Co naprawiam niniejszym. ;P
Wibowit
Sam zrobiłem porównania: https://github.com/tarsa/SortAlgoBox z tym, że między CPU, a GPU oraz między językami programowania. Nie mam ARMów czy PowerPC do testowania to nie testowałem.
KR
Moderator
  • Rejestracja:prawie 21 lat
  • Ostatnio:2 miesiące
  • Postów:2964
2

Dodam jeszcze: kiedy algorytm O(n^2) jest znacznie prostszy oraz n jest na pewno małe lub i tak kod O(n^2) spełnia wymagania wydajnościowe, bo nie znajduje się na krytycznej ścieżce wydajnościowej. W praktyce budżet w projekcie jest ograniczony i lepiej poświęcić go na optymalizację tych fragmentów kodu, które faktycznie mają znaczenie. Jeśli w wyniku zastąpienia O(n^2) gdzieś przez O(n) czas startu aplikacji skróci się z 5 s do 4,99 s, to raczej nie ma to sensu.

No i druga sprawa, o czym pisał już Shalom - często algorytmy o niższej złożoności mają wyższą stałą. Więc dla małych n może się okazać, że O(n^2) faktycznie jest szybsze od O(n), a O(n) jest szybsze od O(1).

edytowany 1x, ostatnio: Krolik
Satanistyczny Awatar
Albo jak zejście do O(N) wymaga tak porytej implementacji, że sam C'thulhu by się wystraszył. ;)
cepa
  • Rejestracja:ponad 22 lata
  • Ostatnio:4 dni
1
  • kiedy deadline jest na wczoraj
  • kiedy klient mało płaci
  • kiedy ma działać "ch*jowo ale stabilnie"
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)