Random Range mit Gewichtung

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Random Range mit Gewichtung

    Hallo,

    immer wieder stehe ich vor dem "Problem" einen Zufallsbereich so zu verschieben, dass sich nicht der Bereich an sich verschiebt sondern nur die Wahrscheinlichkeit.

    Beispiel:
    Aus einem Bereich 10-20 sollen Zahlen per Zufall generiert werden.
    Allerdings sollten mehr kleinere Zahlen herauskommen als größere in Abhängigkeit einer Gewichtungsangabe.
    Wichtig hierbei ist aber, dass sich der Bereich nicht verkleinern soll.
    Das heißt - natürlich soll nach wie vor auch mal die 20 gezogen werden, aber immer prozentual nicht so oft wie eben die 10 oder eben alle Zahlen dazwischen.
    Also reicht ein einfaches Shifting / Bias nicht aus.

    Leider habe ich bis jetzt kein Node gefunden, was diese auf den ersten Blick einfache Aufgabe erfüllen kann.
    Es gibt als einiges das Bool with Weight Node, aber nichts in Richtung Float.
    Folglich geht man selbst ran und bastelt sich eine Funktion, die auf folgender Überlegung fußt.

    Vorab ist es wichtig eine hochperformante Lösung zu bieten.
    Die Angabe der Gewichtung erfolgt von 0-1 - wobei 0.5 gleich 50% - also eine Normalverteilung darstellt.
    Alle anderen Werte darunter und darüber verschieben die Wahrscheinlichkeit.
    Meine Überlegung ist jetzt je nach Richtung der 0.5 Referenz den Zufallsbereich einfach zu vergrößern, um ihn abschließend mit einem Clamp wieder abzuschneiden.
    Ich wollte auf jeden Fall verhindern, dass ich mich mit < und >= rumschlagen muss.
    Es sollte eine rein rechnerische Funktion sein ohne zusätzliche Branch- oder Select-Abfragen.
    Daher muss alles, was unter 0.5 liegt automatisch vom Min abgezogen und darüber liegende Wert zum Max dazuaddiert werden ohne den jeweiligen anderen Pol zu beeinflußen.
    Allerdings möchte ich aus Performancegründen, wenn möglich, nur addieren und multiplizieren.
    Subtraktion und Division sind rechnerisch viel aufwändiger für die CPU als ihre Gegenspieler.
    "*0.5" ist schneller als "/2" - eine Erkenntniss, die man seit der BASIC-Scripterei aus den 80ern mal gelernt hat. ;)
    Einzig das Ermitteln des effektiven Bereichs lässt nur Subtraktion zu, da ein Negieren mit anschließender Addition dann doch wieder kontraproduktiv wäre.
    Das Schöne ist, dass man sein Random bequem in nur eine Vector-Variable setzen kann: x=min, y=max, z= weight.

    Siehe Screenshot ist das, was ich als Lösung präsentieren kann.

    Der Sinn des Threads ist:
    1. für alle, die das benötigen ist das hier eine gut funktionierende Lösung
    2. die Frage, ob ihr Verbesserungen der Funktion sehen könnt.

    Nachtrag:
    Ein kleines Problem ist, dass alle Zahlen, die in den vergrößerten Bereich kommen dann immer absolut zu Min oder Max werden.
    Man müßte die erweiterte Range dann anstatt zu clampen wieder zusammenstauchen.
    Vielleicht fällt euch ja etwas dazu ein.
    Bilder
    • RandomRangeWeight.jpg

      74,06 kB, 1.563×316, 62 mal angesehen
    F99

    Dieser Beitrag wurde bereits 11 mal editiert, zuletzt von Franz99 ()

  • Leider erwies sich die Vorstellung alles rechnerisch zu gestalten doch als Pleite.
    Das Problem ist wirklich, dass das Clamp alle Werte jeweils auf Min und Max abschneidet, wenn der Bereich vergrößert wird.
    Und dementsprechend sieht auch das Resultat aus.

    Ergo habe ich eine neue Version erstellt und diese funktioniert nun wie gewünscht und einwandfrei.
    Mit dem Random Bool Weight und leider 2 Selects konnte ich zumindest die Branches umschiffen.
    Dafür ist das Gewicht jetzt auch absolut anzugeben.

    Beispiel:
    Setzt man einen Weight-Wert von 0.1 wird die Chance 90% sein, dass sich der Zufallswert in den ersten 10% des Bereiches befindet.
    Im Grunde strecht man die Wahrscheinlichkeitsverteilung um den Mittelpunkt eines definierten Bereichs ohne, dass Werte durch erweiterte Bereiche verloren gehen.
    Warum stellt Epic nicht so ein Node zur Verfügung oder habe ich es nur noch nicht gefunden?
    Bilder
    • RandomRangeWeight2.jpg

      105,79 kB, 1.537×528, 56 mal angesehen
    F99

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von Franz99 ()

  • Das Ganze hier ist ein simples Beispiel, wie man sich in Codes und Logiken verlieren kann, ohne dabei zu beachten, dass die Lösung im Grunde so einfach und sogar Anfängerhaft ist.
    Oh je - entweder man löscht den Thread oder nutzt meinen Quatsch für andere Ideen.

    Dass man natürlich, wie auch z.B. das Bool Weight Node, einfach nur Zufallswert und Wahrscheinlichkeitswert jeweils für Min und Max mit einem >= vergleichen muss, ist meinem Gehirn nicht so schnell entsprungen.
    Das Ganze jetzt als Lösung nochmal mit Screenshot zu präsentieren, wäre sogar zu peinlich und nicht den Webspace wert das zu tun.

    Sorry, dass ich evtl. den einen oder anderen verwirrt habe, aber das unglaubliche Feedback auf meinen Thread, hätte mir schon mal eher verraten können, dass da irgendwas nicht hinhaut. ^^
    Also überlest diesen Thread einfach - er existiert überhaupt nicht! <-- Fehler in der Matrix! ;)
    F99
  • Also ich dachte immer, dass folgendes Schema gültig ist:

    C++ Experte --> Blueprint = Kinderkram
    Blueprint-Experte --> C++ = Studium erforderlich

    Übrigens... anhand der Random Bool with Weight Lösung sieht man bereits wie einfach man denken sollte und was ich meinte:

    Quellcode

    1. bool UKismetMathLibrary::RandomBoolWithWeight(float Weight)
    2. {
    3. //If the Weight equals to 0.0f then always return false
    4. if (Weight <= 0.0f)
    5. {
    6. return false;
    7. }
    8. else
    9. {
    10. //If the Weight is higher or equal to the random number then return true
    11. return Weight >= FMath::FRandRange(0.0f, 1.0f);
    12. }
    13. }
    Alles anzeigen
    F99

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von Franz99 ()

Unreal®, Unreal Engine, the circle-U logo and the Powered by Unreal Engine logo are trademarks or registered trademarks of Epic Games, Inc. in the United States and elsewhere.