как сделапть на C# вероятность "ДА" 20%

  • Автор темы Автор темы PROforum
  • Дата начала Дата начала

PROforum

Client
Регистрация
17.08.2014
Сообщения
252
Реакции
19
Баллы
18
Здравствуйте. Подскажите как сделать на с#. Чтоб случайный ответ "ДА" выпадал с 20 % вероятностью ( "НЕТ" соответственно с 80%) и записывался в переменную проекта.
 
Если просто и на кубиках:
- создать список на десять строк, где ДА 2 шт., а НЕТ 3 шт.
- брать рандомно

UP. Сразу не заметил что на с# нужно. Можно сделать аналогичным способом.
 
  • Спасибо
Реакции: PROforum
как-то так:

C#:
Развернуть Свернуть Копировать
int r = Global.Classes.rnd.Next(0,99);
if (r<20)
{
    // меньше 20%
}
else
{
    // больше 20%
}
 
  • Спасибо
Реакции: PROforum
Это глобальный рандом, его использует постер.
Когда мы работаем со списком\таблицей мы лочим, чтоб несколько потоков не взяли одну и ту же строку.
Моё типичное поведение следующее: если код вносит изменения во внешнем источнике и с этим источником будет работать несколько потоков, тогда участок кода, который вносит изменения, оборачивается lock'ом; если же код только берёт данные, без какой-либо их модификации, то я и не лочу такой код.

А почему тут int r = Global.Classes.rnd.Next(0,99); надо делать лок? Какая проблема может произойти если несколько потоков одновременно обратятся к методу Global.Classes.rnd.Next()?

Я не пытаюсь дое*аться:) Я хочу разобраться в тонкостях работы.
 
А почему тут int r = Global.Classes.rnd.Next(0,99); надо делать лок? Какая проблема может произойти если несколько потоков одновременно обратятся к методу Global.Classes.rnd.Next()?
Конечно, не каждый это знает, но Random не потокобезопасен и его использование в шаблоне сопряжено с риском просто "сломать" этот объект,
что приведёт к дублированию результатов или утечке памяти или просто вылету постера.

C#:
Развернуть Свернуть Копировать
Random rnd = Global.Classes.rnd;
lock(rnd)
{
    // далее работа с ним
    // rnd.Next(...)
}
 
Конечно, не каждый это знает, но Random не потокобезопасен и его использование в шаблоне сопряжено с риском просто "сломать" этот объект,
что приведёт к дублированию результатов или утечке памяти или просто вылету постера.

C#:
Развернуть Свернуть Копировать
Random rnd = Global.Classes.rnd;
lock(rnd)
{
    // далее работа с ним
    // rnd.Next(...)
}
а другой вариант есть ?
 
Создавайте в общем коде свой Random для каждого потока:
C#:
Развернуть Свернуть Копировать
new Random(Guid.NewGuid().GetHashCode())
Это как именно, яснее можно?Чтоб не опытный чел понял
 
Это как именно, яснее можно?Чтоб не опытный чел понял
Общий код:
C#:
Развернуть Свернуть Копировать
namespace ZennoLab.OwnCode
{
    public class CommonCode
    {
        public static object SyncObject = new object();
   
        [ThreadStatic] public static Random Rnd = new Random(Guid.NewGuid().GetHashCode());
    }
}
В экшене:
C#:
Развернуть Свернуть Копировать
if(CommonCode.Rnd.NextDouble() < 0.2)
{
    project.SendInfoToLog("1");
}
else
{
    project.SendInfoToLog("0");
}

int r = Global.Classes.rnd.Next(0,99); if (r<20)
Помню задавался подобным вопросом и такие примеры не советовали использовать, из-за их не особой рандомности.
Советовали сравнивать с double (между 0.0 и 1.0).
 
  • Спасибо
Реакции: one и Roman48
Вы также можете использовать:
project.Variables["result"].Value = Macros.TextProcessing.Spintax("{YES|YES|NO|NO|NO|NO|NO|NO|NO|NO}", false);
 
Вы также можете использовать:
project.Variables["result"].Value = Macros.TextProcessing.Spintax("{YES|YES|NO|NO|NO|NO|NO|NO|NO|NO}", false);
Последнее false что означает? И как процентуально по спинтаксу результат будет выпадать?
 
  • Спасибо
Реакции: Yuriy Zymlex и one
И как процентуально по спинтаксу результат будет выпадать?
60485
 
  • Спасибо
Реакции: one
Помню задавался подобным вопросом и такие примеры не советовали использовать, из-за их не особой рандомности.
Советовали сравнивать с double (между 0.0 и 1.0).

Можно юзать класс, который используется в криптографии, для генерации случайного числа. Это если начинать уже маньячить.:D
RNGCryptoServiceProvider
 
Общий код:
C#:
Развернуть Свернуть Копировать
namespace ZennoLab.OwnCode
{
    public class CommonCode
    {
        public static object SyncObject = new object();
  
        [ThreadStatic] public static Random Rnd = new Random(Guid.NewGuid().GetHashCode());
    }
}
В экшене:
C#:
Развернуть Свернуть Копировать
if(CommonCode.Rnd.NextDouble() < 0.2)
{
    project.SendInfoToLog("1");
}
else
{
    project.SendInfoToLog("0");
}
А если не глобал задавать а просто
var rnd = new Random();
тоже лок надо ?
 
А если не глобал задавать а просто
var rnd = new Random();
тоже лок надо ?
тоже интересует.
А тут уже проблема, что вам придётся (зачем-то) создавать объект класса CommonCode и где-то его хранить.

Ещё вариант, в первом экшене вызывать:
C#:
Развернуть Свернуть Копировать
project.Context["rnd"] = new Random(Guid.NewGuid().GetHashCode());
В последующих:
C#:
Развернуть Свернуть Копировать
Random rnd = project.Context["rnd"];
// return rnd.Next(1, 10);
 
А тут уже проблема, что вам придётся (зачем-то) создавать объект класса CommonCode и где-то его хранить.
Я не понял при чем здесь CommonCode и где его хранить надо ....

попробуйте кубик создать и выполнить
C#:
Развернуть Свернуть Копировать
var rnd = new Random();
var p = rnd.Next(200);
return p;

Вопрос остается, надо ли лок при этом использовать.
 
Как в этот код переменную вставить, вместо 20?
C#:
Развернуть Свернуть Копировать
int i = int.Parse(project.Variables["pr"].Value);
Random r = new Random();
if(r.Next(1,100) < i) return "Да";
else return "Нет";
 
  • Спасибо
Реакции: dmitlife и Roman48
C#:
Развернуть Свернуть Копировать
int i = int.Parse(project.Variables["pr"].Value);
Random r = new Random();
if(r.Next(1,100) < i) return "Да";
else return "Нет";
Если в переменной pr будет цира 60 то 60% будет да или нет?
 
Что то не то, вроде работает, но что-то не так.
Ставлю этот сниппет проверяю, 50-50 и через раз, ставлю 60 видно
C#:
Развернуть Свернуть Копировать
Random rnd = Global.Classes.rnd;
lock(rnd)
{
    Random r = new Random();
if(r.Next(1,100) < 50) return "Да";
else return "Нет";
}

Этот почему-то, как то не так
C#:
Развернуть Свернуть Копировать
int i = int.Parse(project.Variables["pr"].Value);
Random r = new Random();
if(r.Next(1,100) < i) return "Да";
else return "Нет";
 
хз)) Вроде да, по успеху будет 60% идти.

Честно не понял, что ты написал. Да он не работает, щас проверю еще раз.
Работает, но как то не так, если сделать 50 на 50 должно через раз, быть да и нет, а он этого не делает. Я хотел очередность, куда идти в процентах устанавливать.
 
Работает, но как то не так, если сделать 50 на 50 должно через раз, быть да и нет, а он этого не делает.
С чего ты взял)) Так не должно быть. Это вероятность, ее нельзя предсказать. Снипет работает, проверил.
Я хотел очередность, куда идти в процентах устанавливать.
Если надо очередность, то это совсем другая задача.
 

Кто просматривает тему: (Всего: 0, Пользователи: 0, Гости: 0)