GD Star Rating
loading...

Подскажите, как это сделать? Чтобы при генерации случайного целого числа в указанном диапазоне, вероятность выпадения чисел из центра диапазона была выше.
Не могу простого решения придумать, получаются какие-то жуткие конструкции.

размер 475x265, 12.90 kb

Админы и сочувствующие посетители hardblog.net посчитали злободневным:поговорим вместе ?

38 Responses to Подскажите, как это сделать?

  1. Ebahlam:

    sin(random()*PI), например

  2. TsrSwet:

    : То, что нужно! Спасибо!

  3. Operado:

    Возможно, тебе подойдёт нормальное распределение. А алгоритмов ГПСЧ с нормальным распределением – куча

  4. TsrSwet:

    : А сгладить график как можно? Чтобы не такая крутая синусоида была, а положе.
    (школьную программу вообще забыл напрочь)

  5. Ebahlam:

    : я даже не догадываюсь что ты имеешь ввиду под “положе”.

  6. TsrSwet:

    : Ну не такой крутой график, а более пологий. Грубо говоря, чтобы числа с краев диапазона выпадали не в 10 раз реже центра, а всего в 5, например.

  7. TsrSwet:

    : Не, вообще не совсем то.
    По формуле round(sin(random()*PI)*10)
    число 10 получается чаще всего.
    А мне нужно, чтобы числа из центра (5 и 6) выпадали чаще, а цифры по краям (0 и 10) реже.

  8. TsrSwet:

    : Мне бы простое что-нибудь, на яве.

  9. KoZlo:

    сидел пытался придумать способ заставить wolframalpha такие распределения рисовать. не вышло

  10. TsrSwet:

    В общем, что-то корявое сделал, но получилось примерно то, что нужно.

    size=9;
    x = (int) Math.round(Math.pow(Math.random(), 0.6d) * (int)(size/2));
    if (Math.random()>0.5f) { x=size-x;}

  11. TeaSm:

    Да наверняка же до жопы реализаций нормального распределения на базе равномерного

  12. TsrSwet:

    : Я нашел несколько алгоритмов, но нифига в них не понял.

  13. TeaSm:

    : если тебе нужна просто абстрактно вогнутость по центру без какой-то конкретики в параметрах, делай просто тупо сумму или среднее арифметическое нескольких равномерно распределенных величин, вроде Math.random() + Math.random() + Math.random(), чем больше слагаемых, тем ближе распределение к нормальному и тем больше вероятность среднего значения

  14. TeaSm:

    : не вогнутость а выгнутость, в смысле

  15. TsrSwet:

    : Что-то я не понял.. Я сложил пять раз random(), сумму округлил. Да, значения “2” и “3” чаще всего выпадают. А вот “0” из тысячи раз выпал только один раз. Это какая-то уж очень большая выпуклость.

  16. TeaSm:

    : сложи два рандома

  17. TsrSwet:

    : Ясно, я не так понял твое сообщение, думал, чем больше слагаемых, тем лучше. С двумя рандомами получается! Спасибо.

  18. TeaSm:

    : чем больше слагаемых, тем больше вероятность выпадения среднего значения и ниже вероятность крайних значений, а сама кривая распределения получается ближе к гауссиане, я это имел ввиду

  19. TsrSwet:

    : С двумя рандомами тоже весьма крут график. Разница в частоте выпадения “0” и “5” – примерно в 20 раз.
    round((random+random)*5)

  20. TeaSm:

    : насколько я себе представляю работу round он и так даёт меньше вероятности выпадения крайних значений, т.е. даже при просто round(random*n) вероятность 0 и n в два раза меньше, чем у любого другого числа, не?

  21. TsrSwet:

    : Блин, точно. Меня мучили подозрения, что что-то не так в этой формуле..

  22. Nikbad:

    вот тебе простое и на Java: new Random().nextGaussian()

  23. Mvxmac:

    Допустим, что ты нарисовал кусок синуса, только длинной не pi, а 10. Если смотреть на это как на функцию плотности распределения, то ее запишем так:
    sin(pi*x/10)*pi/20
    Функция распределения будет:
    1/2-1/2 cos((pi*x)/10)
    А ее обратная функция:
    (10*arccos(1-2*x))/pi

    Таким образом, теория нам говорит, что тебе нужно /* если это варварский С */:
    (10/PI)*acos(1-2*((double)rand()/(double)RAND_MAX))

    Но, конечно, лучше воспользоваться существующей библиотекой.
    (Спасибо альфе, и надеюсь я тоже ничего не перепутал.)

  24. TsrSwet:

    : Проверил экселем, вроде похоже на правду, только диапазон непонятный. С RAND_MAX=10 результаты от 0.1 до 2.1

    Ну да неважно уже, (rand+rand)/2 дает нужный мне результат.
    Я не адронный коллайдер рассчитываю, мне для игрушки 🙂
    Надо случайно заполнить поле клеточками, так, чтобы к центру было погуще, а по краям мало.
    Получается так:

    размер 178x272, 16.73 kb

  25. Mvxmac:

    : Я пытался получить диапазон 10 ))) RAND_MAX чем больше, тем лучше.

    До меня только сейчас дошло, что тебе нужны целые числа, и да – твой метод вполне подходит. Лучше только взять оба ранда от 0 до 5 и просто складывать, чтобы избежать округлений и получить симметричное распределение.

  26. TsrSwet:

    : Ты имеешь в виду (int)(rand*5+rand*5)?
    Чем это отличается от (int)((rand+rand)/2 *10)?

    По-моему распределение вполне симметричное получается, если миллион раз посчитать, значение 4 встречается с такой же частотой, как значение 5.

  27. Mvxmac:

    : Так rand у тебя не целый? А, и ты его round округляешь. Тогда ОК.
    А диапазон все-таки от 0 или от 1?
    Это JavaScript? Я так понимаю, что для каждой точки генерится четыре псевдо-рандома. “Using an implementation-dependent algorithm or strategy” – если генератор совсем херовый, то теоретически между четверками может быть сильная корреляция.

  28. TsrSwet:

    : У меня Java, Math.random() возвращает double.
    Я не знаю, про какие четыре псевдо-рандомы ты говоришь 🙂

    Мне нужно получить случайное целое число от 0 до 9, (int)((Math.random()+Math.random())/2 *10) дает то, что нужно.

  29. Mvxmac:

    : Ты генеришь две координаты, для каждой из них используются два rand. Скорее всего это четыре последовательные элемента, созданные единственным LCG. Теория учит нас, что если у LCG статистические свойства последовательных элементов вполне приличные, это еще не значит, что последовательных пар, троек, четверок и т.д. не будет полной катастрофы, и есть пример этого: http://en.wikipedia.org/wiki/RANDU

  30. TsrSwet:

    : Думаю, пользователи моей игрушки переживут подобную катастрофу. 🙂

  31. Remodin:

    А не проще ли вбить этот колокол в массив длиной 100 и считать как
    return my_array[random(100)]

  32. Phplinux:

    : Ты все действительные числа хочешь вбить в массив? 🙂

  33. Phplinux:

    : Ну то есть если уметь нужный колокол генерировать в массив, не составляет проблем взять i-ый его элемент и так, без массивов.

  34. Remodin:

    : ну колокол можно и ручками нарисовать, на клетчатой бумажке или из инетов скачать. Генерировать не надо. А потом сотню чисел заколотить в массив. Тупо, но будет работать как железный лом.

  35. Sukon:

    Random.gaussian(1.0, 2.0)

  36. Risin:

    : пополам поделить не забудь

  37. Risin:

    : ох ёпта, да ведь этому посту тыща лет, опять я разсредоточился

Добавить комментарий