Reihenfolge per Zufallsgenerator bestimmen

Ratoncito

Level-1
Beiträge
163
Reaktionspunkte
2
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich möchte die Reihenfolge von 7 Aktivitäten per Zufallsgenerator bestimmen. Den Ablauf stelle ich mir so vor:

Nehmen wir mal an die Aktivitäten wären von A bis G bezeichnet.
Zu einer bestimmten Bedingung werden diesen Aktivitäten Zahlen von 1 bis 7 zugeordnet und anschließend der Reihe nach abgearbeitet.

Ich möchte, dass diese Aktivitäten jedesmal in einer anderen Reihenfolge ablaufen.

Für Eure Hilfe im Voraus vielen Dank
 
Hallo Wolfgang,

mal in OSCAT geschaut? Da gibt es RND-Funktionen, die den Timer nutzen, um Pseudo-Zufallszahlen zu erzeugen. Und dann kannst Du z.B. nach Größe der Zahlen sortieren, um die Reihenfolge festzulegen.

Gruß
Jens
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hier ganz viel gänzlich ungetesteter PseudoCode:

Verwendete Variablen:
Code:
giA       globales INT Array [0..6]
giP       globale  INT Variable
grR       globale  REAL Variable
    
tbEnd     temporäre BOOL Variable
    
tiBis     temporäre INT Variable
tiIdx1    temporäre INT Variable
tiIdx2    temporäre INT Variable
tiTmp     temporäre INT Variable
    
trR       temporäre REAL Variable

Init-Routine:
Code:
// = = = = = < Init: "im Hochlauf der PLC" > = = = = =

// - - - < Array 0..6 initialisieren mit 1..7 > - - -
tiTmp := giA[0] ;
For tiIdx1 := 0 To 6 Do
    giA[tiIdx1] := (tiIdx1 + tiTmp) Mod 7 + 1 ;
End_For ;

// - - - < Startwert für grR bilden > - - -
If giP < 2 OR  giP > 32740 Then
    giP := 2 ;
Else
    Repeat
        giP = giP + 1 + giP Mod 2 ;
        tiBis := Real_To_Int(Sqrt(Int_To_Real(giP))) ;
        tbEnd := True ;
        For tiIdx1 := 3 To tiBis By 2 Do
            If giP Mod tiIdx1 = 0 Then 
                tbEnd := False ;
                Exit ;
            End_If ;     
        End_For ;
    Until tbEnd
    End_Repeat ;
End_If ;
trR := Sqrt(Int_To_Real(giP)) ;
grR := trR - Int_To_Real(Real_To_Int(trR)) ;

Nächste Array-Belegung bilden:
Code:
// = = = = = < Next: "Verwirbeln des Array" > = = = = =

// - - - < Array rotieren > - - -
tiTmp:= giA[0] ;
For tiIdx1 := 0 To 5 Do
    giA[tiIdx1] := giA[tiIdx1 + 1] ;
End_For ;
giA[6] := tiTmp ;

// - - - < Idx1 bilden > - - -
trR := grR * 997.0 ;
grR := trR - Int_To_Real(Real_To_Int(trR)) ;
tiIdx1 := Real_To_Int(grR * 7.0) ;

// - - - < Idx2 bilden > - - -
trR := grR * 997.0 ;
grR := trR - Int_To_Real(Real_To_Int(trR)) ;
tiIdx2 := Real_To_Int(grR * 7.0) ;

// - - - < ggfs Idx2 korrigieren > - - -
If tiIdx1 = tiIdx2 Then 
    tiIdx2 := (tiIdx2 + 3) Mod 7 ;
End_If ;

// - - - < 2 Elemente tauschen > - - -
tiTmp:= giA[tiIdx1] ; 
giA[tiIdx1] := giA[tiIdx2] ;
giA[tiIdx2] := tiTmp ;
 
Hallo,

@Heinilein
Morgen werde ich mich damit beschäftigen und sicherlich mehr als nur eine Frage haben.


@Jens
Bei Oscat habe ich einige Stunden rumgesucht, aber nichts gefunden. Eventuell nicht an der richtigen Stelle gesucht, war heute eh nicht mein Tag.


Vielen Dank und noch einen schönen Abend.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich habe sicherlich auch danach gesucht. Ich habe auch einige Beiträge zu Zufallsgenerator gefunden, aber die Beiträge waren recht alt und eventuell vorhandener Code gelöscht. Unter den Downloads bin ich auch nicht fündig geworden.

Aber wie schon bemerkt, heute war nicht mein Tag.
 
Ich glaube, dass findest Du unter den mathematischen Funktionen... Such mal nach RND.
Besser nach RDM bzw. RDM2.

Aber wie schon bemerkt, heute war nicht mein Tag.
Doch! Du weisst es nur noch nicht! ;)

RND ist runden (ROUND). Das Zauberwort lautet RANDOM. Man kann nach dem kompletten Wort suchen (und u.a. viele unpassende Dinge finden) oder nach (z.B.) RDM.

PS:
In #3 benutze ich zu Fuss gemachte ZufallsZahlen. Prinzip: Multiplikation mit 997 und plattmachen der Vorkommastellen.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

quote_icon.png
Zitat von Ratoncito
Aber wie schon bemerkt, heute war nicht mein Tag.
Doch! Du weisst es nur noch nicht!

Dann wollen wir mal hoffen...

Eigentlich kann es heute nur besser werden :)

Trotz dem gestrigen Debakel werde ich mich heute zuerst noch mal mit der Rechnerei um Zeit und Datum beschäftigen.
 
Hallo Heinileini,

den Code aus Deinem Beitrag#3 habe ich in einen Baustein eingefügt. Ja es funktioniert, ich sitze vor dem Laptop und sehe staunend viele sich ständig ändernde Zahlen.

Nur, wie könnte ich nun meine 7 Variablen, ich nenne sie mal A ... G in zufälliger Reihenfolge starten?

Ich bin mal wieder ahnungslos.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

Du erzeugst pro Buchstaben A..G eine Zahl. Am Ende sortierst Du sie nach Größe, schon hast Du eine zufällige Reihenfolge.

ja, so habe ich mir das auch gedacht. :)

Die Frage ist nur wie?

Der Zufallsgenerator aus Beitrag#3 scheint ja zu funktionieren, aber wie erhalte ich nun die Zahlen für A ... G, und wie sortiere ich das.
 
Was willst du eigentlich sortieren? Erst möchtest du eine zufällige Reihenfolge und dann willst du wieder sortieren? Grundsätzlich ordnest du doch deinen Aktionen A..G die Zahlen 1..7 fest zu, oder nicht? Also A bekommt fest den Wert 1, B den Wert 2 usw. Jetzt ziehst du die erste Zahl und arbeitest die entsprechende Aktion ab. Dann ziehst du solange eine nächste Zahl, bis diese ungleich der schon gezogenen ist und arbeitest die nächste Aktion ab. Das machst du so lange, bis jede Zahl einmal gezogen wurde.

Übrigens, man muss es nicht verkomplizieren :ROFLMAO: .
Wenn man eine genügend große Ganzzahl hernimmt, welche man bis in die letzten Stellen unmöglich beeinflussen kann (z.Bsp. die Tageszeit in Millisekunden, einen Timer, die Systemzeit etc.), und dann mit MOD 7 (für den Bereich 1..7) arbeitet, erhält man auch ein zufälliges Ergebnis. Ich habe das vor langer Zeit mal getestet, die Ergebnisse gezählt und für gut befunden.
 
Zuletzt bearbeitet:
Was willst du eigentlich sortieren? Erst möchtest du eine zufällige Reihenfolge und dann willst du wieder sortieren? Grundsätzlich ordnest du doch deinen Aktionen A..G die Zahlen 1..7 fest zu, oder nicht? Also A bekommt fest den Wert 1, B den Wert 2 usw. Jetzt ziehst du die erste Zahl und arbeitest die entsprechende Aktion ab. Dann ziehst du solange eine nächste Zahl, bis diese ungleich der schon gezogenen ist und arbeitest die nächste Aktion ab. Das machst du so lange, bis jede Zahl einmal gezogen wurde.

Da komme ich jetzt nicht mit....
Die Zahlen 1..7 sind ja Zufallszahlen. Er möchte A..G in zufälliger Reihenfolge aufrufen... Wenn ich also die Zufallszahlen der Größe nach sortiere, bekomme ich eine zufällige Reihenfolge... daher das Sortieren.

Ich denke, wie immer, gibt es mehrere Lösungswege:
Du nimmst ein zweidimensionales Array. In der ersten Dimension speicherst Du fest A..G, in der zweiten dynamisch die Zufallszahlen und sortierst dann nach den Zufallszahlen. Danach gehst Du von oben nach unten durch, die Zufallszahlen interessieren jetzt in der zweiten Dimension nicht mehr, jetzt guckst Du nur noch in die erste und liest aus, welche Aktion A..G zu startest.

Eine weitere ist, die Zufallszahlen in zwei Arrays zu speichern: Quasi eine Abwandlung von der ersten Lösung und vielleicht das, was Dagobert meint. Im ersten Array hast Du jetzt über den Arrayindex die Zuordnung der Zahlen zu A..G. Das zweite Array sortierst Du und "ziehst" jetzt die Zahlen nach und nach. Suchst die dann im ersten Array und hast über den Index die Aktion, die Du starten willst.

Du kannst auch Zahlen zwischen 1..7 generieren über den Zufallsgenerator und nimmst dann die Aktion A..G, die Du ausführen willst. Hierbei mußt Du nur aufpassen, daß Du eine Aktion nicht mehrfach ausführst. Taucht eine Zahl mehrfach auf, mußt Du den Zufallsgenerator ggf. mehrfach anschmeißen.

Array sortieren geht z.B. über _ARRAY_SORT aus Oscat.

Du kannst auch versuchen, ein Array 1..7 anzulegen und dieses in jedem Durchgang über _ARRAY_SHUFFLE aus Oscat durcheinanderzuwürfeln. Damit kommst Du eigentlich am Schnellsten zum Ergebnis. Hab ich gerade erst gesehen, daß es diese Funktion gibt...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

mal wieder nicht richtig ausgedrückt :)

A ... G nach Zufall unterschiedliche Zahlen zuweisen und dann in Reihenfolge der zugewiesenen Zahl ausführen.

PS
Bedenkt bitte, ich bin Erstklässler - bilde die Quadratwurzel von... :)
Je einfacher - je besser
 
Zuletzt bearbeitet:
Code:
Reihenfolge : Array[1..7] of Real := 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0;
Dummy : BOOL;
x : INT;

Dummy := _ARRAY_SHUFFLE(pt:=ADR(Reihenfolge), size:=7);

for x:=1 to 7 do
    case REAL_TO_INT(Reihenfolge[x]) of
             1: //Anweisung für A
             2: //Anweisung für B
             3: //Anweisung für C
             ...
     end_case;
end_for;
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin Wolfgang,
die zufällige Reihenfolge steht in den 7 Elementen des Array.
Du schaust nacheinander giA[0] .. giA[6] an und führst das aus, was "drinsteht". Ist natürlich als Zahl kodiert (1..7) und nur Du weisst, was die Zahlen bedeuten.
Im folgenden mache ich die Zuordnung 1 entspricht Aktion A, 2 entspricht Aktion B, u.s.w..
Code:
    IF giAct > 6 THEN // irgendwo Sequenz starten durch 'giAct := 0 ;'
        gbActDone := TRUE
        // hier sonst nix tun, d.h. warten, bis giAct im Bereich 0..6 liegt
    ELSIF gbActDone THEN // wenn gbActDone, dann nächste Aktion starten
        gbActDone := FALSE ;
        giAct := giAct MOD 7 ;
        CASE giA[giAct] OF
        1:  
            //  hier Kriterium für Start Aktion A setzen!
            IF "Aktion A fertig" THEN gbActDone := TRUE ; END_IF ; // statt "Aktion A fertig" etwas "sinnvolles" programmieren!
        2:  
            // hier Kriterium für Start der Aktion B setzen!
            IF "Aktion B fertig" THEN gbActDone := TRUE ; END_IF ;
        3:  
            // hier Kriterium für Start der Aktion C setzen!
            IF "Aktion C fertig" THEN gbActDone := TRUE ; END_IF ;
        4:  
            // hier Kriterium für Start der Aktion D setzen!
            IF "Aktion D fertig" THEN gbActDone := TRUE ; END_IF ;
        5:  
            // hier Kriterium für Start der Aktion E setzen!
            IF "Aktion E fertig" THEN gbActDone := TRUE ; END_IF ;
        6:  
            // hier Kriterium für Start der Aktion F setzen!
            IF "Aktion F fertig" THEN gbActDone := TRUE ; END_IF ;
        ELSE:  
            // hier Kriterium für Start der Aktion G setzen!
            IF "Aktion G fertig" THEN gbActDone := TRUE ; END_IF ;
        END_CASE ; 
    IF gbActDone THEN giAct := giAct + 1 ; END_IF ;
    END_IF ;
Das mag ungeschickt für Deine Anwendung sein, aber da kann ich nur raten ...

Gruss, Heinileini
 
Sorry, aber die Zeile

Dummy := _ARRAY_SHUFFLE(pt:=ADR(Reihenfolge), size:=7);

meldet einen Fehler, den ich nicht beseitigen kann.

Programmname, Funktion oder Funktionsbausteininstanz an Stelle von '_ARRAY_SHUFFLE [...]

???
 
Zurück
Oben