Seite 3 von 3

Verfasst: 23.10.2008 03:14
von Kaeru Gaman
stimmt... wenn zu wenig eingefüllt wird, wird nicht abgefangen im letzten durchlauf.

die bedingung braucht dann auch eine "Verbrauch den Rest" condition:

Code: Alles auswählen

  If ( AlleAepfel + DieserKorb > Aepfel ) Or ( ( n = Koerbe ) And  AlleAepfel + DieserKorb < Aepfel )
damit kannst du die startwerte dann auch extremer wählen:
374 Äpfel in 12 Körben.
------------------------------
In Korb 1 sind 21 Äpfel.
In Korb 2 sind 29 Äpfel.
In Korb 3 sind 12 Äpfel.
In Korb 4 sind 3 Äpfel.
In Korb 5 sind 13 Äpfel.
In Korb 6 sind 23 Äpfel.
In Korb 7 sind 0 Äpfel.
In Korb 8 sind 20 Äpfel.
In Korb 9 sind 19 Äpfel.
In Korb 10 sind 39 Äpfel.
In Korb 11 sind 10 Äpfel.
In Korb 12 sind 185 Äpfel.
==================
Probe:
21 + 29 + 12 + 3 + 13 + 23 + 0 + 20 + 19 + 39 + 10 + 185 = 374
hier sieht man deutlich, dass der letzte wert aus der reihe fällt, um den Rest aufzubrauchen.
... ob das dann aber so glücklich st, ist noch die zweite Frage.
vielleicht solltest du dann eine GaussRandom benutzen, und die um den Durchschnitt verteilen...

wobei das auch unsinn ist...

Verfasst: 23.10.2008 06:54
von Little John
Xaby hat geschrieben:@Little John,

meine Euphorie nach einigen Tests hält sich in Grenzen.

Ich muss leider meine Liebe wieder zurück nehmen.
Na ob ich dann noch eine Chance habe, in diesem Leben einen Xaby abzubekommen? :D
Xaby hat geschrieben:Das Problem ist, dass sich bei großen Anzahlen von Äpfeln und einer geringen Anzahl an Körben, die Verteilung der Äpfel doch sehr ähnelt.

Es gibt keine Spitzen.

Beispiel: 3 Körbe, 300 Äpfel und ein Limit pro Korb bei 200

Pegelt es sich auf ~100 ein.
Ich war davon ausgegangen dass jeder Korb -- solange er noch nicht voll ist -- die gleiche Chance haben soll, einen Apfel zu bekommen. Und dann ergibt sich das halt so.

Inzwischen haben ja die Kollegen hier noch mehr Code gepostet. Falls das nicht reicht, habe ich noch eine andere Idee.
Kaeru Gaman hat geschrieben:vielleicht solltest du dann eine GaussRandom benutzen, und die um den Durchschnitt verteilen...
Mein folgender Vorschlag basiert darauf, von vornherein normalverteilte Zufallszahlen statt gleichverteilte zu benutzen.
Xaby: "Spiele" mal vorsichtig mit dem Wert für Streuung!

Code: Alles auswählen

; Aepfel zufaellig auf Koerbe verteilen;
; nicht gleichmaessig, sondern normalverteilt (mit begrenzten Korbgroessen)

EnableExplicit

Procedure.f RandomNormal (mean.f=0, stdDev.f=1)
   ; siehe <http://www.purebasic.fr/german/viewtopic.php?t=17013>
   Protected x1.f, x2.f, r.f

   ; random numbers from the open interval ]0, 1[
   x1 = (Random(999998)+1) / 1000000        ; must be > 0 because of Log(x1)
   x2 = (Random(999998)+1) / 1000000

   r = Sqr(-2*Log(x1)) * Cos(2*#PI*x2)
   ProcedureReturn r*stdDev + mean
EndProcedure


Define AnzahlAepfel, AnzahlKoerbe, KorbGroesse, LetzterKorb, i, k
Define.f Mittel, Streuung

;-- gegeben
AnzahlAepfel = 100
AnzahlKoerbe = 20
KorbGroesse = 30

;-- Vorbereitungen
If AnzahlAepfel > AnzahlKoerbe * KorbGroesse
   Debug "Das geht nicht -- Programm abgebrochen!"
   End
EndIf

LetzterKorb = AnzahlKoerbe - 1
Dim Korb(LetzterKorb)
Mittel = LetzterKorb/2
Streuung = Mittel/3             ; diesen Wert zum Experimentieren veraendern!

;-- zufällig verteilen
i = 1
While i <= AnzahlAepfel
   k = Round(RandomNormal(Mittel, Streuung), #PB_Round_Nearest)
   If k >= 0 And k <= LetzterKorb And Korb(k) < KorbGroesse
      Korb(k) + 1
      i + 1                     ; naechster Apfel
   EndIf
Wend

;-- Ergebnis ausgeben
For i = 0 To LetzterKorb
   Debug Korb(i)
Next
Gruß, Little John

Verfasst: 23.10.2008 16:12
von kswb73
@Froggerprogger
Jo danke. Du solltest vorher aber das Array leeren sonst gibt es bei mehreren Durchläufen in einem Programm Probleme. Dein Code ist jetzt in beiden Varianten im Test.

/Edit Mist deinen neuen Code zuspät gesehen.

Verfasst: 23.10.2008 20:47
von mk-soft
Hi,

Interessante problem. Habe es versucht rein mathematisch über Restwertberechnung zu lösen

Funktioniert soweit.

Code: Alles auswählen

apfel_gesamt = 12
koerbe = 3

Global Dim zahl.f(4)
Global summe.d, faktor.d

For n = 1 To 500
  ; Init
  apfel = apfel_gesamt
  testsumme = 0
  summe = 0.0
  For i = 1 To koerbe
    zahl(i) = Random(100000000) / 100000000.0
    summe + zahl(i)
  Next
  
  For i = 1 To koerbe
    faktor = apfel / summe
    anzahl.l = Round(zahl(i) * faktor, #PB_Round_Nearest)
    Debug "Korb " + Str(i) + ": " + Str(anzahl)
    apfel - anzahl
    summe - zahl(i)
    testsumme.l + anzahl
  Next
  Debug "------------------------------"
  Debug "Summe: " + Str(testsumme)
  Debug ""
  If testsumme <> apfel_gesamt
    Debug "Fehler Summe"
    End
  EndIf
Next
FF :wink:

Verfasst: 23.10.2008 22:27
von Xaby
@mk-soft

Wo ist die Begrenzung der Menge pro Korb?

Ansonsten schön zufällig :D :allright:

Scheint aber auch sehr langsam zu sein :freak: