Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Bubblesort-Optimierung


Boldar - So 27.07.08 14:22
Titel: Bubblesort-Optimierung
Hallo,
ich suche nach Möglichkeiten, folgenden Code auf Geschwindigkeit zu optimieren


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
program selsort;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  windows;

const maximum = 100000;
const maxtext = '100.000';

type tarr = array [0..maximum] of integer;

procedure SelectionSort(var A: tarr);

  procedure Swap(var X, Y: integer);
  var
    Swp: integer;
  begin
    Swp := X;
    X := Y;
    Y := Swp;
  end;

var
  I, J: Integer;
begin

  for I := Low(A) to High(A) - 1 do
    for J := I + 1 to High(A) do
      if A[I] > A[J] then Swap(A[I], A[J]);
end;

var i: integer;
var a: tarr;
var start : cardinal;

begin
  randomize;
  writeln ('Zufallsgenerator initialisiert');
  start := gettickcount;
  for I := 0 to maximum do
    begin
      a[i]:= random (maxint);
    end;
  writeln (inttostr(start-gettickcount)+ 'Ms Zum erzeugen der Zufallszahlen');
  writeln (maxtext + ' Zufallszahlen erzeugt');
  start := gettickcount;
  selectionsort (a);
  writeln (inttostr(start - gettickcount) + 'Ms Zum Sortieren');
  readln;

end.


Eine Idee wäre es vielleicht, swap als inline zu deklarieren aber wie macht man dass??

Gibt es noch weitere Möglichkeiten der Optimierung??


Delete - So 27.07.08 14:28

das was du gepostet hast, ist ein bubble-sort, kein selection sort. im gegensatz zu 'n bubble wird beim selection eine variable selected und erst zum schluss getauscht. damit sparst du dir etliche swaps.

<HTH> GG

ps: was willste denn jetzt coden, 'n bubble oder 'n selction?


Marc. - So 27.07.08 15:23

Wobei Du bereits einen Fehler im Code hast. Es musst letztendlich writeln (inttostr(gettickcount - start) + 'Ms Zum Sortieren'); heißen.
Vielleicht daher der enorme "Performanceverlust". :zwinker:


Boldar - So 27.07.08 21:14

aaah...
Aber wie können dann Positive Werte auftreten?

EDIT Ach ja, ist ja Cardinal...


EDIT2

Mir is noch was eingefallen:

Wäre es als sortieralgorithmus nicht effizienter, wenn man so vorgeht:

Quelltext
1:
2:
3:
4:
32514    -------> Unsortiert
13254    -------> Elemente mit Wert 1 gesucht und an den Anfang gestellt
12354    -------> Element 2 gesucht und dahinter gestellt
12345    -------> Element 4 hinter die 3 Gestellt


Geht dass und gibts dafür einen Namen???


Fabian E. - So 27.07.08 22:31

Wenn du immer nach dem kleinsten/größten Element suchst und dann hintendran stellst ist das ein Min/max-Sort und in der Laufzeit wenn ich mich nicht irre von O(n²), also nicht sehr effektiv.


Delete - So 27.07.08 22:45

klar geht das, das nennt sich selction sort :-) http://de.wikipedia.org/wiki/SelectionSort

aber jetzt nicht kopieren :-)

und ob es 'n int, float oder string ist pips egal. wichtig ist nur, dass du feststellen kannst was grösser, was kleiner und was gleich gross ist :-)


noch 'n schönes wochenende :-)

PS: hast du jetzt den titel von selction sort nach bubble sort umbennant?


Gausi - Mo 28.07.08 08:44

Ja, der Titel wurde hier zwischen durch geändert...Ist nicht schön, da das, was er da im ersten Post macht, eigentlich kein Bubblesort ist, sondern eher eine komische Variante von Selectionsort, aber egal...

Zur Frage: Man kann Bubblesort so implementieren, dass er im besten Fall schon nach einem Durchlauf fertig ist:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
fertig := False;
While not fertig do
begin
  fertig := True;
  for i := low(A) to High(A)-1 do
    if A[i] > A[i+1then
    begin
      swap(A[i], A[i+1]):
      fertig := False;
    end;
end;


Zur Frage eher Bubble- oder eher Selectionsort: Selectionsort hat immer eine Laufzeit in O(n^2), Bubblesort ist auf sortierten Folgen nach einem Durchlauf fertig, also O(n). Von daher würde ich Bubblesort vorziehen.

Wenn man allerdings wirklich schnell sortieren will, dann nimmt man Quicksort, Heapsort oder Mergesort. ;-)


Marc. - Mo 28.07.08 15:00

user profile iconGausi hat folgendes geschrieben:
Wenn man allerdings wirklich schnell sortieren will, dann nimmt man Quicksort, Heapsort oder Mergesort. ;-)

Für den Vergleich von Sortieralgorithmen gibt es ein schönes Programm: Sortieralgorithmen in Assembler [http://www.codingcrew.de/marty/download.php?count=34].
Allerdings, wie der Name bereits sagt, mit (MASM32)-Assembler geschrieben. Sollte aber dennoch ganz nützlich sein. :)


Thorsten83 - Sa 30.08.08 15:53

Hey,
wenn's um kleine Mengen geht ist der BubbleSort gar nicht so schlecht,
und über 2 kleine Optimierungen kriegt man ihn halt auch relativ schnell:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
void bubbleSort(int[] feld){
  int i;
  int n = feld.length;
  boolean isSorted = false;
  while(!isSorted){
    isSorted = true;
    n--;
    for (i=0 ; i<n ; i++){
      if (feld[i]>feld[i+1]){
        isSorted = false;
        swap(feld, i, i+1);
      }
    }
  }
}


BenBE - Sa 30.08.08 19:24

Mir fällt noch eine auf ;-): for(i=n; i; --i)