TIA Bubbelsort in SCL

Lawdy

Level-1
Beiträge
2
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Forum,
bin noch ziemlich neu was das Thema SPS-Programmierung angeht deswegen bitte ich um Verständnis ^^
Habe folgende Aufgabe erhalten:
Programmiere einen Sortieralgorithmus (Bubbel Sort) in SCL, der Werte 5 Werte aus einem Array in einem DB liest, und anschließend die Werte der Größe nach sortiert ( von klein nach groß, also bspw. 0...1...3...4)
Ich habe mich bereits durch das Forum gelesen aber konnte leider keinen Beitrag bisher auf meine Aufgabenstellung umsetzten
Konnte mich mit Hilfe eines Beitrages im Forum inspirieren leider hat es noch nicht so funktioniert wie ich es mir vorgestellt hatte deshalb hoffe ich auf Hilfe im Forum :D

Hier mein Code:

#Write_Index := 0;


FOR #Read_Index := 0 TO #Anzahl_Sortierwerte DO
IF "Zahlen_sortiererDB".Sortierwerte[#Read_Index] <> 0 THEN
"Zahlen_sortiererDB".Sortierwerte[#Write_Index] := "Zahlen_sortiererDB".Sortierwerte[#Read_Index];
#Write_Index := #Write_Index + 1;
;
END_IF;
END_FOR;




WHILE #Write_Index <= #Anzahl_Sortierwerte DO
"Zahlen_sortiererDB".Sortierwerte[#Write_Index] := 0;
#Write_Index := #Write_Index + 1;
;
END_WHILE;
 
Wikipedia Code:
Code:
bubbleSort2(Array A)   n = A.size
  do{
    swapped = false
    for (i=0; i<n-1; ++i){
      if (A[i] > A[i+1]){
        A.swap(i, i+1)
        swapped = true
      } // Ende if
    } // Ende for
    n = n-1
  } while (swapped)


TIA-Portal Code:
Code:
REPEAT
    #swapped := FALSE;
    FOR #i := 0 TO #Max_Array - 1 DO
        
        IF "Zahlen_sortiererDB".Sortierwerte[#i] > "Zahlen_sortiererDB".Sortierwerte[#i + 1] THEN
            #TmpInt := "Zahlen_sortiererDB".Sortierwerte[#i];
            "Zahlen_sortiererDB".Sortierwerte[#i] := "Zahlen_sortiererDB".Sortierwerte[#i + 1];
            "Zahlen_sortiererDB".Sortierwerte[#i + 1] := #TmpInt;
            #swapped := TRUE;
        END_IF;
    END_FOR;
UNTIL #swapped = FALSE
END_REPEAT;
 
Zuviel Werbung?
-> Hier kostenlos registrieren
#swapped ist eine Variable vom Typ Bool
#TmpInt
ist eine Variable vom Typ Integer ggf. musst Du hier halt auf das Format gehen welches Du in Deinem Array verwendest.
#Max_Array kannst Du durch die Zahl ersetzen, welche Du im Array als Maximum verwendet hast.
Mein Array startet beim Feld 0 was ich auch bevorzuge, wenn Du bei 1 beginnst muss die Schleife angepasst werden.
 
Kleine Anmerkung:

mit den Zeilen

Code:
REPEAT
    #swapped := FALSE;
  
// Hier Schleifencode


UNTIL #swapped = FALSE
END_REPEAT;

wird das Sortieren in einem Zyklus durchgeführt. Das möchte man ja eigentlich auch haben, damit man dann mit den sortieren Werten arbeiten kann. Bei den 5 ist das auch alles kein Problem.

Solltest du nur irgendwann auf die Idee kommen ein sehr großes Array (in Zukunft evtl.) so zu sortieren (und / oder dabei größere Datenmengen / Strukturen dann umkopierst), muss du nur bedenken, dass dies dann so auf die Zykluszeit geht.

Nur am Rande.


-chris
 
Guten Abend Codemonkey,

ich bin auf der suche nach einem Bubbelsort hier gelandent.

Ich möchte aus einem Array 0..4 of Struct genau einen Wert der Struktur sortieren. Leider bekomme ich immer einen Bereichslängen fehler. Kann aber nicht so wirklich einordner weshalb.

Vielen Dank schon mal für deine Hilfe
Time = Int


Hier mein Code:

Code:
IF #sSorieren OR #iSpsNeustartTHEN
    #sBrakePadSort := #BrakePad;

        REPEAT
            #sapped := FALSE;
            FOR #tIndex := 4 TO 0 BY -1 DO
                
                IF  #sSortwierwert[#tIndex]."Time" > #sSortwierwert[#tIndex + 1]."Time" THEN
                    #tFlank := #sSortwierwert[#tIndex];
                    #sSortwierwert[#tIndex] := #sSortwierwert[#tIndex + 1];
                    #sSortwierwert[#tIndex + 1] := #tFlank;
                    #sapped := True;
                END_IF;
            END_FOR;
        UNTIL #sapped = FALSE
        END_REPEAT;
    END_IF;
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Heiße zwar nicht Codemonkey, aber:

Dein Array passt nicht:

Durch
Code:
TO 0 BY -1 DO
wird der index bis auf -1 laufen.

Durch
Code:
#sSortwierwert[#tIndex +1] := #tFlank;
wird der Index in Runde 1 bei 5 starten.

Beide Male außerhalb des Arrays von 0..4 und damit ein Bereichslängenfehler.
 
Hi escride1 danke für die schnelle Antwort.

Also müsste mein Code so aussehen ?

Code:
        [COLOR=#333333][FONT=Courier]IF #sSorieren OR #iSpsNeustartTHEN[/FONT][/COLOR]    #sBrakePadSort := #BrakePad;

        REPEAT
            #sapped := FALSE;
            FOR #tIndex := 0 TO 4 BY  0 DO
                
                IF  #sSortwierwert[#tIndex]."Time" > #sSortwierwert[#tIndex + 1]."Time" THEN
                    #tFlank := #sSortwierwert[#tIndex];
                    #sSortwierwert[#tIndex] := #sSortwierwert[#tIndex + 1];
                    #sSortwierwert[#tIndex + 1] := #tFlank;
                    #sapped := True;
                END_IF;
            END_FOR;
        UNTIL #sapped = FALSE
        END_REPEAT; [COLOR=#333333][FONT=Courier]    END_IF;[/FONT][/COLOR]
 
Ganz ehrlich, ich hab nun nicht die Funktion was da tatsächlich passiert durchgeschaut (lazy),
aber spätestens bei
Code:
FOR #tIndex := 0 TO 4 BY 0 DO
ist klar das es nicht funktionieren kann.
Zähle Schleife von 0 bis 4 im Schritt 0...

Zieh Deinen Code auseinander, nutze Kommentare und schreibe Dir hinter jede Zeile was da passieren soll. Dann bekommst auch einen Durchblick was da passiert.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe mal in der Informatik-Vorlesung mitbekommen, daß der Bubble-Sort Algorithmus völlig ineffizient sein soll, und sich ausschließlich deswegen so lange in den Köpfen halten konnte, weil er einen einprägsamen Namen besitzt...
 
Es ist ziemlich egal, ob Du die Schleife vom kleinsten bis zum grössten Index oder vom grössten Index bis zum kleinsten laufen lässt, wenn Du in der Schleife mit Index + 1 oder Index - 1 auf ein ArrayElement zugreifst, greifst Du irgendwann ins Leere.
Zeigt der Index auf das erste Element, so zeigt Index - 1 "vor" das Array und
zeigt der Index auf das letzte Element, so zeigt Index + 1 "hinter" das Array.
Wieviele Vergleiche benötigst Du denn, um die jeweils zwei benachbarten der n Elemente zu vergleichen?

@Draco
Mag sein, dass der Name BubbleSort mitgeholfen hat, seine Popularität unsterblich zu machen.
Aber ein Vorteil dieses Algorithmus ist, dass er normalerweise [SUP]1[/SUP]) leicht zu verstehen und zu vermitteln ist und deshalb meistens als Einstieg in das Thema Sortieren herhalten muss.
Oft folgt dann auf diesen Einstieg ... nichts weiter ... und schon klebt der Begriff BubbleSort wie BubbleGum nahezu unlösbar am Thema Sortieren.

[SUP]1[/SUP]) Ausnahmen bestätigen die Regel, s. hier. ;)
 
Ich habe mal in der Informatik-Vorlesung mitbekommen, daß der Bubble-Sort Algorithmus völlig ineffizient sein soll, und sich ausschließlich deswegen so lange in den Köpfen halten konnte, weil er einen einprägsamen Namen besitzt...

Er ist zusätzlich auch sehr sehr einfach zu verstehen. Quicksort ist zwar schneller und meine beliebteste Sortierweise auf einer SPS, kann dann aber schon ne richtig harte Nuss sein zu verstehen.

Also zum Lernen ist Bubblesort sicher ne nette Sache. Aber man baut sich die Sortieralgorithmen ja nicht jedesmal neu, also nimmt man dann für den Produktiven Einsatz sicher was effizienteres.

Um diese Inhalte anzuzeigen, benötigen wir die Zustimmung zum Setzen von Drittanbieter-Cookies.
Für weitere Informationen siehe die Seite Verwendung von Cookies.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Er ist zusätzlich auch sehr sehr einfach zu verstehen. Quicksort ist zwar schneller und meine beliebteste Sortierweise auf einer SPS, kann dann aber schon ne richtig harte Nuss sein zu verstehen.

Also zum Lernen ist Bubblesort sicher ne nette Sache. Aber man baut sich die Sortieralgorithmen ja nicht jedesmal neu, also nimmt man dann für den Produktiven Einsatz sicher was effizienteres.

Hast du mal ein Codeauszug zum Quicksort? Das würde mich mal interessieren. Hatte bisher immer nur kleine Arrays sortieren müssen (<16 Elemente, und dort nur UDINT's) also ging das ganz gut und fix mit Bubblesort. Ist ja auch schnell runtergeschrieben. Aber Quicksort würde mich mal interessieren. Muss auch ehrlich gestehen das ich noch garnicht versucht habe es nachzubilden, da es noch nicht nötig war größere Daten schnell zu sortieren. Wäre ganz nett von dir.

Gruß

-chris
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich mach zig Jahre SPS und auch viel I4.0, hatte aber noch nie soviel zu sortieren, dass ich mir Gedanken über die Effizenz von Sortierverfahren auf der SPS machen musste.
Wenn ich selber meine Daten erzeuge, dann füge ich diese lieber bereits an der passenden Stelle, bevor ich hinterher sortieren muss.

Drum mal interessehalbe die Frage: Bei welchenAnlagen / Anwendungsfällen müsst ihr so aufwendig sortieren?

Gruß
Blockmove
 
Ich mach zig Jahre SPS und auch viel I4.0, hatte aber noch nie soviel zu sortieren, dass ich mir Gedanken über die Effizenz von Sortierverfahren auf der SPS machen musste.
Dito. Deswegen war für mich bisher Bubble Sort das Werkzeug meiner Wahl - schnell geschrieben und funktioniert. Ob das Ergebnis dann ein paar Zyklen länger dauert, interessierte bisher in meinen Fällen nicht.
Drum mal interessehalbe die Frage: Bei welchen Anlagen / Anwendungsfällen müsst ihr so aufwendig sortieren?
Mein "Hauptanwendungsfalll" ist die alphabetische Sortierung von einer Rezeptverwaltung. Hier wird der Bubble Sort immer dann angestoßen, wenn ein neues Rezept angelegt wird oder der Name eines bestehenden Rezeptes geändert wird.
 
Ich mach zig Jahre SPS und auch viel I4.0, hatte aber noch nie soviel zu sortieren, dass ich mir Gedanken über die Effizenz von Sortierverfahren auf der SPS machen musste.
Wenn ich selber meine Daten erzeuge, dann füge ich diese lieber bereits an der passenden Stelle, bevor ich hinterher sortieren muss.

Drum mal interessehalbe die Frage: Bei welchenAnlagen / Anwendungsfällen müsst ihr so aufwendig sortieren?

Früher waren das vor allem Verkehrsdaten. Also Achserfassung auf der Strasse um die Fahrzeugdosierungen zu regeln (Zufahrtsmenge von Nebenachsen auf die Hauptachsen der Autobahnen)
Mittlerweile wird das aber auf Servern gemacht.

Heute noch im kleinen Rahmen um Mediane über grössere Zeiträume zu bilden für Strömungsmessungen. Das ginge auch mit Bubblesort weil meist nur an die 30 Werte die Sortiert werden. Aber Effizienz ist doch was schönes :)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Naja ... wenn man aber (wie der TE) 5 Werte umsortieren möchte dann braucht man sich noch keine Gedanken über die mögliche Effizienz eines Sortier-Algorythmus machen ...

@TE:
Hast du dein Problem jetzt im Griff ? Es liegt nicht am "by -1" - das ist die Schrittweite deiner Schleife. Es liebt wahrscheinlich daran, dass deine Array auch nur von 0 bis 4 geht. Das mußt du in der Schleife berücksichtigen, da du ja immer ein Element mit Schleifen-Index +1 ansprichst. Hier wird dein Bereichsfehler entstanden sein ...

Gruß
Larry
 
Ich mach zig Jahre SPS und auch viel I4.0, hatte aber noch nie soviel zu sortieren, dass ich mir Gedanken über die Effizenz von Sortierverfahren auf der SPS machen musste.
Wenn ich selber meine Daten erzeuge, dann füge ich diese lieber bereits an der passenden Stelle, bevor ich hinterher sortieren muss.

Drum mal interessehalbe die Frage: Bei welchenAnlagen / Anwendungsfällen müsst ihr so aufwendig sortieren?

Löcher machen, Vorgabe von einem PC:
10 Datensätze mit max. 100 Postionen die von einem PC UNSORTIERT (!) Kommen (können) und dann noch mal alle 10 Datensätze wegen Verfahroptimierung auf eine X-Achse sortieren. Das mit einer kleinen ET200sp CPU, die auch noch viel Safety macht ...
Warum die SPS sortieren muss, wenn dadrüber ein PC ist der sonst nichts viel machen muss: Gute Frage! War aber nicht verhandelbar. Kunde gab das so vor...
 
Also müsste mein Code so aussehen ?

Code:
        REPEAT
            #sapped := FALSE;
            FOR #tIndex := 0 TO 4 BY  0 DO
                IF  #sSortwierwert[#tIndex]."Time" > #sSortwierwert[#tIndex + 1]."Time" THEN
                    #tFlank := #sSortwierwert[#tIndex];
                    #sSortwierwert[#tIndex] := #sSortwierwert[#tIndex + 1];
                    #sSortwierwert[#tIndex + 1] := #tFlank;
                    #sapped := True;
                END_IF;
            END_FOR;
        UNTIL #sapped = FALSE
        END_REPEAT;
Nicht wirklich.
Was ist #sSortwierwert[#tIndex]."Time"?
Hast Du ein Array of struct, also eine Tabelle mit mehreren Spalten, in der Du die Zeilen nach den Werten in der Spalte "Time" sortieren sollst?

Ungetestet:
Code:
FOR #tMaxIndex := UpperBound - 1 TO 0 BY -1 DO // UpperBound: hier muss der maximal zulässige Index stehen 
    #swapped := FALSE;
    FOR #tIndex := 0 TO #tMaxIndex DO
        IF  #sSortierwert[#tIndex]."Time" > #sSortierwert[#tIndex + 1]."Time" THEN
            #tFlank := #sSortwierwert[#tIndex];
            #sSortierwert[#tIndex] := #sSortierwert[#tIndex + 1];
            #sSortierwert[#tIndex + 1] := #tFlank;
            #swapped := True;
        END_IF;
    END_FOR;
    IF NOT #swapped THEN EXIT; END_IF;
END_FOR;
 
Zurück
Oben