Czy można uzyskać losową liczbę od 1 do 100 i utrzymać wyniki głównie w przedziale 40–60? Chodzi mi o to, że rzadko wychodzi poza ten zakres, ale chcę, aby był głównie w tym zakresie ... Czy jest to możliwe w JavaScript / jQuery?
Teraz używam tylko podstawowego Math.random() * 100 + 1
.
javascript
algorithm
random
numbers
Darryl Huffman
źródło
źródło
Odpowiedzi:
Najprostszym sposobem byłoby wygenerowanie dwóch liczb losowych od 0-50 i dodanie ich razem.
Daje to rozkład nastawiony na 50, w ten sam sposób rzucając dwie tendencje kostek w kierunku 7.
W rzeczywistości, używając większej liczby „kostek” (jak sugeruje @Falco) , możesz przybliżyć się do krzywej dzwonowej:
JSFiddle: http://jsfiddle.net/797qhcza/1/
źródło
Masz tutaj kilka dobrych odpowiedzi, które dają konkretne rozwiązania; Pozwól, że opiszę ci ogólne rozwiązanie. Problemem jest:
Ogólnym rozwiązaniem tego problemu jest wypracowanie funkcji kwantylowej pożądanego rozkładu, a następnie zastosowanie funkcji kwantyli do wyjścia jednolitego źródła.
Funkcja kwantyl jest odwrotny od całki od żądanej funkcji rozkładu . Funkcja rozkładu to funkcja, w której pole pod częścią krzywej jest równe prawdopodobieństwu, że losowo wybrany element będzie w tej części.
Daję przykład, jak to zrobić tutaj:
http://ericlippert.com/2012/02/21/generating-random-non-uniform-data/
Kod tam jest w C #, ale zasady dotyczą każdego języka; dostosowanie rozwiązania do JavaScript powinno być proste.
źródło
Odczytywanie tablic liczb itp. Nie jest wydajne. Powinieneś wziąć mapowanie, które przyjmuje losową liczbę od 0 do 100 i mapuje do rozkładu, którego potrzebujesz. W twoim przypadku możesz wziąć rozkład z największą liczbą wartości w środku zakresu.
f(x)=-(1/25)x2+4x
źródło
x
od 0 do 100 (wzięte z tego pytania ):y = (Math.sin(2 * Math.PI * (x/100 - 1/4)) + 1) / 2
Mógłbym zrobić coś takiego jak ustawienie „szansy”, aby liczba mogła przekroczyć granicę. W tym przykładzie szansa na 20% będzie wynosić 1-100, w przeciwnym razie 40-60:
skrzypce: http://jsfiddle.net/kbv39s9w/
źródło
Musiałem rozwiązać ten problem kilka lat temu, a moje rozwiązanie było łatwiejsze niż jakiekolwiek inne odpowiedzi.
Wygenerowałem 3 losy między granicami i uśredniłem je. To przyciąga wynik do środka, ale pozostawia całkowicie możliwość dotarcia do kończyn.
źródło
BellFactor
3.To wygląda głupio, ale można użyć rand dwukrotnie:
źródło
Jasne, że to możliwe. Zrób losowy 1-100. Jeśli liczba wynosi <30, wygeneruj liczbę z zakresu 1-100, jeśli nie, wygeneruj ją w zakresie 40-60.
źródło
Istnieje wiele różnych sposobów generowania takich liczb losowych. Jednym ze sposobów jest obliczenie sumy wielu równomiernie losowych liczb. Ile liczb losowych zsumujesz i jaki jest ich zasięg, określi, jak będzie wyglądał ostateczny rozkład.
Im więcej liczb zsumujesz, tym bardziej będzie on tendencyjny do środka. Wykorzystanie sumy 1 liczb losowych zostało już zaproponowane w twoim pytaniu, ale jak zauważysz, nie jest tendencyjne w kierunku środka zakresu. Inne odpowiedzi sugerują użycie sumy 2 liczb losowych lub sumy 3 liczb losowych .
Możesz uzyskać jeszcze więcej odchylenia w kierunku środka zakresu, biorąc sumę więcej liczb losowych. W skrajności można przyjąć sumę 99 liczb losowych, z których każda ma wartość 0 lub 1. To byłby rozkład dwumianowy. (Rozkłady dwumianowe można w pewnym sensie postrzegać jako dyskretną wersję rozkładów normalnych). Teoretycznie może to obejmować cały zakres, ale ma tak dużą tendencję do centrum, że nigdy nie należy oczekiwać, że osiągnie punkty końcowe.
Takie podejście oznacza, że możesz dostosować, ile chcesz stronniczości.
źródło
Co z użyciem czegoś takiego:
Sposób, w jaki go kodowałem, pozwala ustawić kilka zmiennych:
pętle = liczba wyników
prób = liczba przypadków, gdy funkcja spróbuje uzyskać liczbę między 40-60, zanim przestanie działać przez pętlę while
Dodano bonus: Używa zrobić do czasu !!! Awesomeness w najlepszym wydaniu
źródło
Można napisać funkcję, która mapuje wartości losowych między
[0, 1)
aby[1, 100]
w zależności od wagi. Rozważ ten przykład:Tutaj wartość jest
0.95
odwzorowywana na wartość między[61, 100]
.W rzeczywistości mamy
.05 / .1 = 0.5
, co po mapowaniu[61, 100]
daje81
.Oto funkcja:
źródło
Oto ważone rozwiązanie dla 3/4 40-60 i 1/4 poza tym zakresem.
źródło
Ok, więc zdecydowałem się dodać kolejną odpowiedź, ponieważ czułem się tak, jakby moja ostatnia odpowiedź, a także większość odpowiedzi tutaj, wykorzystywały jakiś pół statystyczny sposób uzyskania wyniku typu krzywej dzwonowej. Podany poniżej kod działa tak samo, jak podczas rzutu kostką. Dlatego najtrudniej jest zdobyć 1 lub 99, ale najłatwiej zdobyć 50.
źródło
Polecam użycie rozkładu beta do wygenerowania liczby między 0-1, a następnie przeskalowanie. Jest dość elastyczny i może tworzyć wiele różnych kształtów dystrybucji.
Oto szybki i brudny sampler:
źródło
źródło
Najlepszym rozwiązaniem tego problemu jest BlueRaja - Danny Pflughoeft, ale myślę, że warto wspomnieć o nieco szybszym i bardziej ogólnym rozwiązaniu.
Kiedy muszę wygenerować liczby losowe (ciągi, pary współrzędnych itp.) Spełniające dwa wymagania
Zwykle zaczynam od utworzenia tablicy liczb (ciągów, par współrzędnych itp.) Spełniających wymagania (w twoim przypadku: tablicy liczb zawierającej liczby bardziej prawdopodobne wiele razy). Następnie wybieram losowy element tej tablicy. W ten sposób musisz wywołać kosztowną losową funkcję tylko raz na przedmiot.
źródło
Dystrybucja
Rozwiązanie
Ogólne rozwiązanie
źródło
Możesz użyć liczby losowej pomocnika, aby wygenerować liczby losowe w 40-60 lub 1-100:
źródło
Jeśli możesz użyć tej
gaussian
funkcji, użyj jej. Ta funkcja zwraca normalną liczbę za pomocąaverage 0
isigma 1
.95% tej liczby mieści się w zakresie
average +/- 2*sigma
. Twójaverage = 50
isigma = 5
takźródło
Najlepszym sposobem na to jest wygenerowanie liczby losowej, która jest równomiernie rozłożona na pewien zestaw liczb, a następnie zastosowanie funkcji projekcji do zbioru od 0 do 100, w którym prawdopodobieństwo, że projekcja uderzy w pożądane liczby.
Zazwyczaj matematycznym sposobem osiągnięcia tego jest wykreślenie funkcji prawdopodobieństwa liczb, które chcesz. Możemy użyć krzywej dzwonowej, ale dla łatwiejszego obliczenia wystarczy pracować z odwróconą parabolą.
Zróbmy parabolę w taki sposób, aby jej korzenie były równe 0 i 100 bez wypaczania. Otrzymujemy następujące równanie:
Teraz cały obszar pod krzywą od 0 do 100 jest reprezentatywny dla naszego pierwszego zestawu, w którym chcemy wygenerować liczby. Tam generacja jest całkowicie losowa. Wszystko, co musimy zrobić, to znaleźć granice naszego pierwszego zestawu.
Dolna granica to oczywiście 0. Górna granica jest całką naszej funkcji przy 100, czyli
Wiemy więc, że musimy wygenerować liczbę pomiędzy 0 a 166 666. Następnie musimy po prostu wziąć tę liczbę i rzutować ją do naszego drugiego zestawu, który wynosi od 0 do 100.
Wiemy, że liczba losowa, którą wygenerowaliśmy, jest jakąś całką naszej paraboli z wejściem x od 0 do 100. Oznacza to, że po prostu musimy założyć, że liczba losowa jest wynikiem F (x) i rozwiązać dla x.
W tym przypadku F (x) jest równaniem sześciennym, aw postaci
F(x) = ax^3 + bx^2 + cx + d = 0
prawdziwe są następujące stwierdzenia:Rozwiązanie tego dla x daje rzeczywistą liczbę losową, której szukasz, która z pewnością mieści się w przedziale [0, 100] i znacznie większe prawdopodobieństwo, że znajdzie się bliżej środka niż krawędzi.
źródło
Ta odpowiedź jest naprawdę dobra . Ale chciałbym opublikować instrukcje implementacyjne (nie jestem w JavaScript, więc mam nadzieję, że zrozumiesz) dla innej sytuacji.
Załóżmy, że masz zakresy i wagi dla każdego zakresu:
Wstępne informacje statyczne mogą być buforowane:
Boundary[n] = Boundary[n - 1] + weigh[n - 1]
iBoundary[0] = 0
. Próbka maBoundary = {0, 1, 3, 103, 108}
Generowanie liczb:
N
z zakresu [0, Suma wszystkich wag).for (i = 0; i < size(Boundary) && N > Boundary[i + 1]; ++i)
i
zakres i wygeneruj losową liczbę w tym zakresie.Dodatkowa uwaga na temat optymalizacji wydajności. Zakresy nie muszą być zamawiane ani w kolejności rosnącej, ani malejącej, dlatego w celu uzyskania większego zasięgu zasięg o największej wadze powinien być pierwszy, a najmniejszy - ostatni.
źródło