www.vorhilfe.de
- Förderverein -
Der Förderverein.

Gemeinnütziger Verein zur Finanzierung des Projekts Vorhilfe.de.
Hallo Gast!einloggen | registrieren ]
Startseite · Mitglieder · Impressum
Forenbaum
^ Forenbaum
Status VH e.V.
  Status Vereinsforum

Gezeigt werden alle Foren bis zur Tiefe 2

Navigation
 Startseite...
 Suchen
 Impressum
Das Projekt
Server und Internetanbindung werden durch Spenden finanziert.
Organisiert wird das Projekt von unserem Koordinatorenteam.
Hunderte Mitglieder helfen ehrenamtlich in unseren moderierten Foren.
Anbieter der Seite ist der gemeinnützige Verein "Vorhilfe.de e.V.".
Partnerseiten
Weitere Fächer:

Open Source FunktionenplotterFunkyPlot: Kostenloser und quelloffener Funktionenplotter für Linux und andere Betriebssysteme
Forum "Komplexität & Berechenbarkeit" - Aufwand O-Kalkül
Aufwand O-Kalkül < Komplex. & Berechnb. < Theoretische Inform. < Hochschule < Informatik < Vorhilfe
Ansicht: [ geschachtelt ] | ^ Forum "Komplexität & Berechenbarkeit"  | ^^ Alle Foren  | ^ Forenbaum  | Materialien

Aufwand O-Kalkül: Erklärung
Status: (Frage) beantwortet Status 
Datum: 12:01 Mi 08.06.2011
Autor: BlackSalad

Hi!

Ich versuche grad das Zeug mit den Komplexitätsklassen und den landausymbolen zu verstehen.

Und zwar bin ich gerade bei dem O-Kalkül und würde nun gerne die kleinste obere Schranke Berechnen. Bei normalen Zahlen klappt es auch schon ganz gut. Nun muss man aber ja auch oft den Aufwand von einer Funktion berechnen.

Hier mal ein Beispiel:

for (int i=1; i<=n; ++i){
for (int j=1; j<=n; j*=2){
if (j % 2 == 1){
f(i) // O(i)
}else{
g(); // O(1)
}
}
}

Wie gehe ich denn bei sowas vor?
Konstanten fallen ja einfach weg, aber hier hab ich ja keine richtigen Potenzen usw.  

Wäre lieb, wenn mir jemand erklären könnte wie man bei so nem Code vorgeht um die Schrnake zu berechnen.

Danke

        
Bezug
Aufwand O-Kalkül: Antwort
Status: (Antwort) fertig Status 
Datum: 15:36 Mi 08.06.2011
Autor: felixf

Moin!

> Ich versuche grad das Zeug mit den Komplexitätsklassen und
> den landausymbolen zu verstehen.
>  
> Und zwar bin ich gerade bei dem O-Kalkül und würde nun
> gerne die kleinste obere Schranke Berechnen. Bei normalen
> Zahlen klappt es auch schon ganz gut. Nun muss man aber ja
> auch oft den Aufwand von einer Funktion berechnen.
>  
> Hier mal ein Beispiel:
>  
> for (int i=1; i<=n; ++i){
>  for (int j=1; j<=n; j*=2){
>  if (j % 2 == 1){
>  f(i) // O(i)
>  }else{
>  g(); // O(1)
>  }
>  }
>  }
>  
> Wie gehe ich denn bei sowas vor?

Von innen nach aussen.

Den innersten Schritt hast du ja schon: die asymptotischen Laufzeiten von $f(i)$ und $g()$. Jetzt willst du damit die Laufzeit der inneren Schleife

1:
2: for (int j=1; j<=n; j*=2){
3:   if (j % 2 == 1){
4:     f(i) // O(i)
5:   }else{
6:     g(); // O(1)
7:   }
8: }


bestimmen. Dazu beachte erst, welche Werte $j$ annimmt. Es nimmt die Werte $1, 2, 4, 8, 16, [mm] \dots, 2^k$ [/mm] an, mit $k$ maximal mit [mm] $2^k \le [/mm] n$.

Diese Zahlen sind modulo 2 alle 0, ausser 1. D.h. $f(i)$ wird genau einmal durchlaufen (falls $j = 1$ ist), und danach wird $g()$ genau $k - 1$ mal aufgerufen.

Aus [mm] $2^k \approx [/mm] n$ folgt [mm] $\log_2 [/mm] n [mm] \approx [/mm] k$, womit $k = [mm] O(\log [/mm] n)$ ist. Die Gesamtlaufzeit der inneren Schleife ist also $O(i) + [mm] O(\log [/mm] n) [mm] \cdot [/mm] O(1) = O(i + [mm] \log [/mm] n)$.

Jetzt zur aeusseren Schleife. Die wird von $i = 1$ bis $n$ durchlaufen, fuer jeden ganzzahligen Wert $i$ dazwischen einmal. Die asymptotische Laufzeit ist also [mm] $\sum_{i=1}^n [/mm] O(i + [mm] \log [/mm] n) = [mm] O(\sum_{i=1}^n [/mm] i + [mm] \sum_{i=1}^n \log [/mm] n)$. Jetzt ist [mm] $\sum_{i=1}^n [/mm] i = [mm] \frac{n (n + 1)}{2} [/mm] = [mm] O(n^2)$ [/mm] und [mm] $\sum_{i=1}^n \log [/mm] n = n [mm] \log [/mm] n$, womit dies ganze gleich [mm] $O(n^2 [/mm] + n [mm] \log [/mm] n) = [mm] O(\max(n^2, [/mm] n [mm] \log [/mm] n))$ ist. Da [mm] $n^2 \ge [/mm] n [mm] \log [/mm] n$ ist, ist es also gleich [mm] $O(n^2)$. [/mm]

Damit ist die Gesamtlaufzeit [mm] $O(n^2)$. [/mm]

So. Jetzt versuch mal das nachzuvollziehen :-)

LG Felix


Bezug
                
Bezug
Aufwand O-Kalkül: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 13:32 Sa 11.06.2011
Autor: BlackSalad

Wow Danke!

Ich glaube ich habs jetzt verstanden wie das geht.

Man muss also die schleifen einzeln betrachten.

Wenn ich versuch das jetzt mal bisschen zu üben, wenn ich noch ne Frage dazu habe, meld ich mich nochmal.

DankeschöN!

Bezug
                
Bezug
Aufwand O-Kalkül: Frage (reagiert)
Status: (Frage) reagiert/warte auf Reaktion Status 
Datum: 14:28 Sa 11.06.2011
Autor: BlackSalad

Hätt nochmal ne Frage. Hab jetzt ein paar durchgespielt, bin mir aber bei der da nicht so sicher:

1: for (int i=1; i<=n; ++i){
2:     for (int j=1; j<=i; ++j){
3:         if (j % 2 == 1){
4:            h(i, j); // O(j)
5:         }else{
6:            g(); // O(1)
7:            }
8:         }
9:     }

Also muss ich ja jetzt erst mal nach der inneren schleife schauen:

j nimmt die werte von 1 bis i-1 an.

Also 1, 2, 3, 4, 5 usw.
also j=j+1.




also ist j % 2 == 1 nur im fall von j=2 true.

Also wird h(j) nur einmal ausgeführt pro aufruf der inneren schleife.

und g() wird k-1 mal ausgeführt und kann vernachlässigt werden, da da immer ein linearer Aufwand vorliegt und der Aufwand O(j) somit schon größer ist.


Nun also zur äßeren Schleife:

for (int i=1; i<=n; ++i)

diese wird (n-1) mal ausgeführt.
und bei jeder ausführung wird auch die innere schleife ausgeführt.

Nur wie mache ich jetzt weiter?



Bezug
                        
Bezug
Aufwand O-Kalkül: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 12:39 So 12.06.2011
Autor: BlackSalad

hat sich erledigt.

Bezug
Ansicht: [ geschachtelt ] | ^ Forum "Komplexität & Berechenbarkeit"  | ^^ Alle Foren  | ^ Forenbaum  | Materialien


^ Seitenanfang ^
ev.vorhilfe.de
[ Startseite | Mitglieder | Impressum ]