[C]смоделировать вероятность
я имею в виду функцию, которая с вероятностью p выдаёт 1, а с вероятностью (1-p) выдаёт 0
Делить на RAND_MAX нельзя, у тебя получится неравномерное распределение. Для того, чтобы смоделировать маленькую вероятность, надо просто вызывать rand несколько раз. Типа два события с вероятностью 0.1 вместе выполняются с вероятностью 0.01
ну да, я эти общие идеи понимаю, просто торможу, как свести к вероятности p
Тебе нужна вообще произвольная вероятность?
ага, ну т.е. она хранится в double p, подаю эту переменную функции, и эта функция с вероятностью p говорит ok
long long_rand
{
return long)rand * RAND_MAX + (long) rand;
}
При необходимости взять большее число вызовов rand до достижения желаемой точности.
После этого, ты сможешь делать:
int isOk(double p)
{
return double)long_rand / long) RAND_MAX) * long)RAND_MAX < p;
}
bool RandBool(double prob) {
// RAND_MAX = 100; // говорят в С нельзя менять.
if (prob > 0) {
do {
prob *= RAND_MAX;
if (prob >= 1)
return rand < int(prob + 0.5);
} while (rand == 0);
}
return false;
}
rand == 0 ровно в 1/32768 случаев, совсем не ясна твоя идея.
Разве в твоём примере будет равномерное распределение вероятности?
rand == 0 ровно в 1/32768 случаев, совсем не ясна твоя идея."Типа два события с вероятностью 0.1 вместе выполняются с вероятностью 0.01"

rand == 0 ровно в 1/RAND_MAX случаев, или я путаю?
RAND_MAX не меняется в Си.

может в коде я где-нть и ошибся, но идея в целом выражена
double next_prob = prob * RAND_MAX;
if (next_prob >= RAND_MAX)
return rand < prob;
Это условие выполняется только при prob равном единице.
поправил, теперь вроде должно работать
Будет, но надо к RAND_MAX добавить 1.
Разве в твоём примере будет равномерное распределение вероятности?

prob *= RAND_MAX;
if (prob >= 1)
return rand < prob;
Даже если поправить на RAND_MAX+1, то у тебя при p равном 0.001 условие будет выполняться с вероятностью ~0.000977


это уже тонкости, добавь +1 в нужных местах.
я тут стратегией занимаюсь



у Красина стратегическая точность всё-таки повыше."стратегическая точность" - это как? Эти слова как рядом оказались?
Мой способ - это просто аналитическое расширение его способа. В том смысле, что его способ - есть случай второй итерации моей функции. Причем его способ с делением, а мой - нет.
Слова рядом оказались, потому что ты написал про стратегию.
"стратегическая точность" - это как? Эти слова как рядом оказались?
Мой способ - это просто аналитическое расширение его способа. В том смысле, что его способ - есть случай второй итерации моей функции. Причем его способ с делением, а мой - нет.

Слова рядом оказались, потому что ты написал про стратегию.Стратегия - это web page
только у тебя rand вызывается два раза на n-1 итерациях.не угадал.
Не угадал чего? Что два раза вызывается - так и есть. А что в rand есть деления... Может и нет, но я не думаю, что ряд сдвигов и перестановка элементов массива в памяти гораздо лучше одного деления. Давай продолжим спор, когда ты напишешь код так, что погрешность твоего метода будет меньше 1%.
а ка ты мерял распределение?
или аналитикой вывел?
А распределение я никак не мерял, у тебя погрешность в вероятности. Как я сказал, для p = 0.0001 вероятность возврата true будет 0,000092.
Сколько же по-твоему раз вызовется rand в твоём коде, если при первой итерации p будет меньше 1.0?один!

ты меня так смутил, что я даже проверил!
Ну вот, вызывается 1 раз и потом ещё 1 раз. Я просто ошибся в том, что написал. Ладно, с этой стороны всё ок. Вернёмся к погрешности...
может ты тогда поделишься своими выкладками, а то у меня все нормально получается...
щас подумаем...

Это значит, что при 3.2767 срабатывание будет на числах 0, 1, 2, 3. Эти числа выкидываются с вероятностью ~0,000122; и т.п.
так что правлю код на +0.5...
еще замечания будут?

а сбило меня с толку, что неявное приведение в паскале работает как округление в отличие от С

Я ошибся в выкладках. А предложенное тобою решение только ухудшило ситуацию. Впрочем, отрезая десятичную часть ты никогда не добьёшься стабильно малой погрешности.
2) я тебя огорчу, но на RAND_MAX=32768 далеко не уедешь... Дискретность останется всегда... В моем примере дискретность остается в точности такая же, как и в rand для p=O(0.1) и скачками уменьшается при p-> 0.
Альтернатива - это написание полностью своего генератора с меньшей дискретностью, чем rand.
Но это совсем другая история, хотя тоже вполне реальная...
2. Я не требовал убрать дискретность, я просто сравнивал с тем, что у Красина. Для приведённых в первом топике чисел у него погрешность меньше 1%.
я просто сравнивал с тем, что у Красина. Для приведённых в первом топике чисел у него погрешность меньше 1%.согласен, это потому что у него всегда юзается 2 rand а уменя не всегда, а только при необходимости "углубления" к нулю. Мою процедуру можно легко заставить делать 2 итерации (чтобы юзалось 2 вызова ранд-а) и тогда точности сравняются.


Ну свяжи и посмотри, что получаетсявсе очень просто:
bool RandBool(double prob) {
// RAND_MAX = 100; // говорят в С нельзя менять.
if (prob > 0) {
do {
prob *= RAND_MAX * RAND_MAX;
if (prob >= 1)
return rand*RAND_MAX+rand < int(prob + 0.5);
} while (rand == 0 && rand == 0);
}
return false;
}

bool f(double p) {
if (p > 0.1) {
return rand < RAND_MAX * p;
} else {
return f(0.2) && f(p*5);
}
}
Только нужно знать квантиль нормального распределения.
Оставить комментарий
stm7868162
Как с помощью rand смоделировать, например, вероятность p=0.007, или p=0.0000000001 (во втором случае меньше, чем 1/RAND_MAX)?А то что-то я туплю