Zufallszahlen

Getting started ... Alles für einen gelungenen Start.
17 Beiträge • Seite 1 von 2 (current) Nächste
17 Beiträge Seite 1 von 2 (current) Nächste

Zufallszahlen

Beitrag von Abapsocke (ForumUser / 49 / 6 / 0 ) »
Ich möchte Zufallszahlen erstellen und suche dafür eine Möglichkeit in ABAP. Die entsprechenden Funktionsbausteine sind bei mir nicht vorhanden. Daher kann ich sie nicht nutzen.
Zudem brauche ich zahlen im Bereich von 1-100 etwa. (die meisten eher 1-10 oder 1-20)

Wie kann ich das in ABAP bewerkstelligen?
Ich habe im Netz ein paar vorschläge gefunden die sich leider auf die fehlenden Fubas beziehen.

gesponsert
Stellenangebote auf ABAPforum.com schalten
kostenfrei für Ausbildungsberufe und Werksstudenten


Re: Zufallszahlen

Beitrag von lausek (ForumUser / 64 / 2 / 20 ) »
Hast du es schon mit cl_abap_random versucht?

Code: Alles auswählen.

" min und max müssen nicht zwingend Konstanten sein
  CONSTANTS:
    c_min TYPE i VALUE 1,
    c_max TYPE i VALUE 100.

" Random Generator erzeugen - Uhrzeit als seed, da sonst immer das Gleiche rauskommt!
  DATA(o_random) = cl_abap_random=>create( CONV i( sy-uzeit ) ).

" float( ) gibt eine Gleitkommazahl zwischen 0 und 1 zurück
" Diese Formel ist eine beliebte Programmierübung
  w_num = CONV i( c_min + o_random->float( ) * ( c_max - 1 ) ).

Re: Zufallszahlen

Beitrag von a-dead-trousers (Top Expert / 4395 / 223 / 1182 ) »
Klasse CL_ABAP_RANDOM

EDIT: Zu spät :oops:
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: Zufallszahlen

Beitrag von Abapsocke (ForumUser / 49 / 6 / 0 ) »
da hängt er sich bei mir an DATA auf.
btw:
Mit Klassen habe ich bei ABAP noch nicht geantwortet. Ist dabei etwas besonders zu beachten?

Re: Zufallszahlen

Beitrag von schick (ForumUser / 52 / 5 / 15 ) »
Vermutlich hast du ein Release älter 7.4, dann geht die inline Deklaration nicht.

Statt

Code: Alles auswählen.

DATA(o_random) = cl_abap_random=>create( CONV i( sy-uzeit ) ).
müsstest du dann mit

Code: Alles auswählen.

o_random = cl_abap_random=>create( CONV i( sy-uzeit ) ).
arbeiten und das Feld o_random vorher mit DATA deklarieren.

Beitrag von lausek (ForumUser / 64 / 2 / 20 ) »
Ich kann mir nichts vorstellen was an Klassen besonders sein soll. Darauf kommen wir dann zurück wenn du ein spezifisches Problem hast ^^


Das wäre jetzt auch kompatibel zu älteren Versionen:

Code: Alles auswählen.

  DATA:
        o_random TYPE REF TO cl_abap_random,
        w_num    TYPE i.

  w_num = sy-uzeit.
  o_random = cl_abap_random=>create( w_num ).

"...
  w_num = c_min + o_random->FLOAT( ) * ( c_max - 1 ).

Re: Zufallszahlen

Beitrag von Abapsocke (ForumUser / 49 / 6 / 0 ) »
als was müsste in dem Fall das Feld o_random deklariert werden.

Ich habe jetzt einfach mal Type sy-uzeit verwendet.

Nun bekomme ich den Fehler :

Re:

Beitrag von Abapsocke (ForumUser / 49 / 6 / 0 ) »
lausek hat geschrieben:Ich kann mir nichts vorstellen was an Klassen besonders sein soll. Darauf kommen wir dann zurück wenn du ein spezifisches Problem hast ^^


Das wäre jetzt auch kompatibel zu älteren Versionen:

Code: Alles auswählen.

  DATA:
        o_random TYPE REF TO cl_abap_random,
        w_num    TYPE i.

  w_num = sy-uzeit.
  o_random = cl_abap_random=>create( w_num ).

"...
  w_num = c_min + o_random->FLOAT( ) * ( c_max - 1 ).

das wars, danke.

Re: Zufallszahlen

Beitrag von black_adept (Top Expert / 4089 / 127 / 940 ) »
Aber warum verwendest du CL_ABAP_RANDOM->FLOAT wenn du scheinbar eine zufällige Integerzahl haben willst? Dafür gibt es doch CL_ABAP_RANDOM_INT oder die Methode INTINRANGE in der Klasse CL_ABAP_RANDOM
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Zufallszahlen

Beitrag von black_adept (Top Expert / 4089 / 127 / 940 ) »
Und noch ein Nachtrag: Wenn das eine Programmierübung sein sollte um gleichmäßig verteilte Zahlen von c_min bis c_max zu erhalten stimmt das auch nicht, falls zwischen c_min und c_max noch weitere Zahlen liegen.
Wenn c_min z.B. 1 ist und c_max 10 ist dann sollten ja eigentlich alle Zahlen von 1-10 ca gleich oft auftauchen - aber bei deiner Implementierung bekommen die Zahlen 1 und 10 jeweils 1/18 aller Zahlen und die Zahlen 2-9 jeweils 1/9.
Einfach mal einen Loop bauen und das System zählen lassen....
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Zufallszahlen

Beitrag von Abapsocke (ForumUser / 49 / 6 / 0 ) »
Was ist denn der Unterschied zwischen FLOAT und INT? Wenn ich richtig liege, dann ist Float für Zahlen mit Fließkommastelle, also tatsächlich in meiner derzeitigen Anfrage, wo ich ganze Zahlen brauche erstmal nicht so wichtig. Tatsächlich brauche ich aber zumindest Kommazahlen (auch wenn diese am Ende wieder gerundet werden) im Verlauf meiner Arbeit.

Was den zweiten Nachtrag betrifft: ja, ich brauche letztendlich Zahlen, so als würde ich sie auswürfeln. Klar wäre ein System gut, bei dem letztendlich alle Zahlen gleich häufig auftreten. Für meine Übungszwecke ist es nicht ganz so wichtig, da ich weiß das man im Bereich von Zufallsgeneratoren da noch mit ganz anderen Mitteln arbeiten kann. Wenn es dafür aber eine einfache Lösung gibt, dann interessiert mich das natürlich sehr.

Konkret geht es hier um eine Übung bei der ich alle Einzelthemen die ich über ABAP gelernt habe zusammen fasse und anwende. Dies mache ich in der Form eines Spiels, das relativ simpel aufgebaut ist, bei dem ich aber alle gelernten Dinge abhaken kann.

Was ist der Unterschied der verschiedenen genannten Methoden?

Re: Zufallszahlen

Beitrag von black_adept (Top Expert / 4089 / 127 / 940 ) »
Abapsocke hat geschrieben:Tatsächlich brauche ich aber zumindest Kommazahlen (auch wenn diese am Ende wieder gerundet werden) im Verlauf meiner Arbeit.
Warum?
Abapsocke hat geschrieben:Was den zweiten Nachtrag betrifft: ja, ich brauche letztendlich Zahlen, so als würde ich sie auswürfeln. Klar wäre ein System gut, bei dem letztendlich alle Zahlen gleich häufig auftreten [...] Wenn es dafür aber eine einfache Lösung gibt, dann interessiert mich das natürlich sehr.
Dafür gibt es CL_ABAP_RANDOM_INT oder die Methode INTINRANGE in der Klasse CL_ABAP_RANDOM ( déjà vu )
Abapsocke hat geschrieben: da ich weiß das man im Bereich von Zufallsgeneratoren da noch mit ganz anderen Mitteln arbeiten kann.
Soso - was genau weißt du denn da bzw. was sind das für Mittel - das würde mich gerade mal stark interessieren.
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Zufallszahlen

Beitrag von DeathAndPain (Top Expert / 1941 / 257 / 412 ) »
Ich würde da einfach einen GET TIME machen und dann die hintersten Stellen als Zufallsziffern missbrauchen. Oder zu Programmbeginn einen GET RUN TIME und dann später wieder einen, wenn man wieder eine Zufallszahl braucht. Solange zwischen den beiden GET RUN TIMEs mindestens eine Benutzeraktion liegt (so dass das System auf eine Eingabe wartet), hat man da im Milli- und Mikrosekundenbereich perfekte Zufallszahlen. Teilweise auch ohne Benutzeraktion, einfach mit irgendeinem Datenbankzugriff... es ist mir nicht gelungen, experimentell zu ergründen, ob ein JOIN, eine inhaltliche Subquery oder eine EXISTS-Subquery am performantesten ist, weil die Laufzeiten auch abgesehen vom Caching derart drastisch streuen (mehrere 100%), dass die einzelne Laufzeit als komplett zufällig angesehen werden muss - gerade im Bereich der hinteren Stellen. Auf solch SAP-Server ist halt immer eine Menge los, vor allem wenn er, wie heutzutage üblich, auf einer virtuellen Maschine läuft und sich die Hardware mit soundsoviel anderen teilt.

Testcode war:

Code: Alles auswählen.

*&---------------------------------------------------------------------*
*& Report ZTEST_TABLE_SEARCH
*&---------------------------------------------------------------------*
REPORT ZTEST_TABLE_SEARCH2.

DATA: T_OBJID TYPE STANDARD TABLE OF HROBJID WITH HEADER LINE,
      I TYPE I,
      J TYPE I,
      RUNTIME TYPE I.

SELECTION-SCREEN COMMENT 1(83) TEXT-COM.

PARAMETERS: JN_FIRST RADIOBUTTON GROUP ONE,
            SB_FIRST RADIOBUTTON GROUP ONE,
            EX_FIRST RADIOBUTTON GROUP ONE.

*** START-OF-SELECTION ***
START-OF-SELECTION.

  CASE 'X'.
    WHEN JN_FIRST.
      PERFORM SELECT_WITH_JOIN.
      WRITE: / 'Join:', RUNTIME, 'microseconds'.
      WRITE: / LINES( T_OBJID ), 'table entries'.
      PERFORM SELECT_WITH_SUBQUERY.
      WRITE: / 'Subquery:', RUNTIME, 'microseconds'.
      WRITE: / LINES( T_OBJID ), 'table entries'.
      PERFORM SELECT_WITH_EXISTS.
      WRITE: / 'Exists-Clause:', RUNTIME, 'microseconds'.
      WRITE: / LINES( T_OBJID ), 'table entries'.
    WHEN SB_FIRST.
      PERFORM SELECT_WITH_SUBQUERY.
      WRITE: / 'Subquery:', RUNTIME, 'microseconds'.
      WRITE: / LINES( T_OBJID ), 'table entries'.
      PERFORM SELECT_WITH_JOIN.
      WRITE: / 'Join:', RUNTIME, 'microseconds'.
      WRITE: / LINES( T_OBJID ), 'table entries'.
      PERFORM SELECT_WITH_EXISTS.
      WRITE: / 'Exists-Clause:', RUNTIME, 'microseconds'.
      WRITE: / LINES( T_OBJID ), 'table entries'.
    WHEN EX_FIRST.
      PERFORM SELECT_WITH_EXISTS.
      WRITE: / 'Exists-Clause:', RUNTIME, 'microseconds'.
      WRITE: / LINES( T_OBJID ), 'table entries'.
      PERFORM SELECT_WITH_SUBQUERY.
      WRITE: / 'Subquery:', RUNTIME, 'microseconds'.
      WRITE: / LINES( T_OBJID ), 'table entries'.
      PERFORM SELECT_WITH_JOIN.
      WRITE: / 'Join:', RUNTIME, 'microseconds'.
      WRITE: / LINES( T_OBJID ), 'table entries'.
  ENDCASE.

*&---------------------------------------------------------------------*
*&      Form  SELECT_WITH_JOIN
*&---------------------------------------------------------------------*
FORM SELECT_WITH_JOIN.
  GET RUN TIME FIELD I.
  SELECT OBJID INTO TABLE T_OBJID FROM PA0001
    JOIN HRP1001 ON HRP1001~SOBID = PA0001~PERNR
   WHERE PA0001~WERKS = 'Z001'
     AND PA0001~BEGDA <= SY-DATUM
     AND PA0001~ENDDA >= SY-DATUM.
  GET RUN TIME FIELD J.
  RUNTIME = J - I.
ENDFORM.

*&---------------------------------------------------------------------*
*&      Form  SELECT_WITH_SUBQUERY
*&---------------------------------------------------------------------*
FORM SELECT_WITH_SUBQUERY.
  GET RUN TIME FIELD I.
  SELECT OBJID INTO TABLE T_OBJID FROM HRP1001
   WHERE SOBID IN ( SELECT PERNR FROM PA0001
                     WHERE WERKS = 'Z001'
                       AND PA0001~BEGDA <= SY-DATUM
                       AND PA0001~ENDDA >= SY-DATUM ).
  GET RUN TIME FIELD J.
  RUNTIME = J - I.
ENDFORM.

*&---------------------------------------------------------------------*
*&      Form  SELECT_WITH_EXISTS
*&---------------------------------------------------------------------*
FORM SELECT_WITH_EXISTS.
  GET RUN TIME FIELD I.
  SELECT OBJID INTO TABLE T_OBJID FROM HRP1001
   WHERE EXISTS ( SELECT PERNR FROM PA0001
                     WHERE PERNR = HRP1001~SOBID
                       AND WERKS = 'Z001'
                       AND PA0001~BEGDA <= SY-DATUM
                       AND PA0001~ENDDA >= SY-DATUM ).
  GET RUN TIME FIELD J.
  RUNTIME = J - I.
ENDFORM.

Re: Zufallszahlen

Beitrag von black_adept (Top Expert / 4089 / 127 / 940 ) »
DeathAndPain hat geschrieben: hat man da im Milli- und Mikrosekundenbereich perfekte Zufallszahlen
Ich hoffe du hast jetzt auch einen Beleg für diese Aussage und dass diese Zahlen tatsächlich besser zufallsverteilt sind als die Random-Klassen und auch dass man damit gut Zufallszahlen im Bereich zwischen 1 und 1.000.000 erzeugen kann
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Zufallszahlen

Beitrag von DeathAndPain (Top Expert / 1941 / 257 / 412 ) »
Ich weiß nicht, wie gut die Random-Klassen arbeiten, wohl aber, dass es keinen bekannten mathematischen Algorithmus gibt, der perfekte Zufallszahlen (die den Gesetzen der Stochastik vollständig standhalten) erzeugen kann. Die Uhrzeit hingegen ist ein ebenso zufälliger Wert, wie wenn man einen Würfel wirft. Natürlich nicht, wenn zwischen zwei Abgriffzeitpunktenin etwa eine konstante Rechenzeit liegt. Wenn wir aber Rechenzeiten haben, die wie bei meinen Tests wild zwischen 85.641 und 517.211 schwanken, dann wird man bei den ersten Stellen sicherlich noch rechenzeitabhängige Einflüsse wahrnehmen können. Die hinteren Stellen sidn dann aber rein zufällig, da sie von der tatsächlichen Rechenzeit nicht abhängig sind.

Zugegebenermaßen erhält man damit nur 3-4 verwendbare Stellen, da die Rechenzeit insgesamt zu kurz ist, um noch mehr völlig umstandsunabhängige Stellen zu erzeugen. Ggf. müsste man etwas machen, was mehr Rechenzeit in Anspruch nimmt (da reichen wenige Sekunden, um alle Stellen im Milli- und Mikrosekundenbereich nutzen zu können.

Hat man eine Benutzerinteraktion dazwischen, also etwas, bei dem SAP auf eine Benutzereingabe wartet, dann hat man sowieso gewonnen, denn wann der Benutzer da Enter drückt, ist hinsichtlich der Milli- und Mikrosekundenwerte völlig zufällig.

Vergleichbare Themen

6
Antw.
17620
Views
Mit ABAP Zufallszahlen erstellen
von Azreal » 06.02.2009 09:38 • Verfasst in Tips + Tricks & FAQs

Newsletter Anmeldung

Keine Beiträge verpassen! Wöchentlich versenden wir lesenwerte Beiträge aus unserer Community.
Die letzte Ausgabe findest du hier.
Details zum Versandverfahren und zu Ihren Widerrufsmöglichkeiten findest du in unserer Datenschutzerklärung.

Unbeantwortete Forenbeiträge

Daten an Tabelle binden
vor 2 Tagen von Bright4.5 1 / 770
aRFC im OO-Kontext
vor 4 Wochen von ralf.wenzel 1 / 2392
Hilfe bei SWEC/SWE2
letzen Monat von retsch 1 / 8977