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

PROforum

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

molotok

Client
Регистрация
17.04.2015
Сообщения
733
Благодарностей
358
Баллы
63
Если просто и на кубиках:
- создать список на десять строк, где ДА 2 шт., а НЕТ 3 шт.
- брать рандомно

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

Voronin

Client
Регистрация
30.09.2019
Сообщения
76
Благодарностей
54
Баллы
18
как-то так:

C#:
int r = Global.Classes.rnd.Next(0,99);
if (r<20)
{
    // меньше 20%
}
else
{
    // больше 20%
}
 
  • Спасибо
Реакции: PROforum

Alexmd

Client
Регистрация
10.12.2018
Сообщения
1 021
Благодарностей
1 385
Баллы
113
C#:
Random r = new Random();
if(r.Next(1,100) < 20) return "Да";
else return "Нет";
 
  • Спасибо
Реакции: Hannes и Roman48

Yuriy Zymlex

Moderator
Команда форума
Регистрация
24.10.2016
Сообщения
6 373
Благодарностей
3 297
Баллы
113
Последнее редактирование:

nicanil

Client
Регистрация
06.03.2016
Сообщения
2 242
Благодарностей
1 804
Баллы
113

Yuriy Zymlex

Moderator
Команда форума
Регистрация
24.10.2016
Сообщения
6 373
Благодарностей
3 297
Баллы
113
Последнее редактирование:
  • Спасибо
Реакции: JurgenZolle

nicanil

Client
Регистрация
06.03.2016
Сообщения
2 242
Благодарностей
1 804
Баллы
113
Это глобальный рандом, его использует постер.
Когда мы работаем со списком\таблицей мы лочим, чтоб несколько потоков не взяли одну и ту же строку.
Моё типичное поведение следующее: если код вносит изменения во внешнем источнике и с этим источником будет работать несколько потоков, тогда участок кода, который вносит изменения, оборачивается lock'ом; если же код только берёт данные, без какой-либо их модификации, то я и не лочу такой код.

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

Я не пытаюсь дое*аться:-) Я хочу разобраться в тонкостях работы.
 

Yuriy Zymlex

Moderator
Команда форума
Регистрация
24.10.2016
Сообщения
6 373
Благодарностей
3 297
Баллы
113
А почему тут int r = Global.Classes.rnd.Next(0,99); надо делать лок? Какая проблема может произойти если несколько потоков одновременно обратятся к методу Global.Classes.rnd.Next()?
Конечно, не каждый это знает, но Random не потокобезопасен и его использование в шаблоне сопряжено с риском просто "сломать" этот объект,
что приведёт к дублированию результатов или утечке памяти или просто вылету постера.

C#:
Random rnd = Global.Classes.rnd;
lock(rnd)
{
    // далее работа с ним
    // rnd.Next(...)
}
 

luk911

Client
Регистрация
17.01.2013
Сообщения
1 542
Благодарностей
579
Баллы
113
Конечно, не каждый это знает, но Random не потокобезопасен и его использование в шаблоне сопряжено с риском просто "сломать" этот объект,
что приведёт к дублированию результатов или утечке памяти или просто вылету постера.

C#:
Random rnd = Global.Classes.rnd;
lock(rnd)
{
    // далее работа с ним
    // rnd.Next(...)
}
а другой вариант есть ?
 

Yuriy Zymlex

Moderator
Команда форума
Регистрация
24.10.2016
Сообщения
6 373
Благодарностей
3 297
Баллы
113
  • Спасибо
Реакции: LaGir и Roman48

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
742
Баллы
113

Yuriy Zymlex

Moderator
Команда форума
Регистрация
24.10.2016
Сообщения
6 373
Благодарностей
3 297
Баллы
113
Это как именно, яснее можно?Чтоб не опытный чел понял
Общий код:
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

Vvafel

Client
Регистрация
24.12.2017
Сообщения
80
Благодарностей
34
Баллы
18
Вы также можете использовать:
project.Variables["result"].Value = Macros.TextProcessing.Spintax("{YES|YES|NO|NO|NO|NO|NO|NO|NO|NO}", false);
 

one

Client
Регистрация
22.09.2015
Сообщения
6 793
Благодарностей
1 264
Баллы
113
Вы также можете использовать:
project.Variables["result"].Value = Macros.TextProcessing.Spintax("{YES|YES|NO|NO|NO|NO|NO|NO|NO|NO}", false);
Последнее false что означает? И как процентуально по спинтаксу результат будет выпадать?
 

zarufakis

Client
Регистрация
22.03.2019
Сообщения
1 527
Благодарностей
883
Баллы
113
  • Спасибо
Реакции: Yuriy Zymlex и one

Vvafel

Client
Регистрация
24.12.2017
Сообщения
80
Благодарностей
34
Баллы
18
  • Спасибо
Реакции: one

Moadip

Client
Регистрация
26.09.2015
Сообщения
509
Благодарностей
823
Баллы
93
Помню задавался подобным вопросом и такие примеры не советовали использовать, из-за их не особой рандомности.
Советовали сравнивать с double (между 0.0 и 1.0).
Можно юзать класс, который используется в криптографии, для генерации случайного числа. Это если начинать уже маньячить.:D
RNGCryptoServiceProvider
 

luk911

Client
Регистрация
17.01.2013
Сообщения
1 542
Благодарностей
579
Баллы
113
Общий код:
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();
тоже лок надо ?
 

artomka

Client
Регистрация
23.08.2018
Сообщения
159
Благодарностей
93
Баллы
28

Yuriy Zymlex

Moderator
Команда форума
Регистрация
24.10.2016
Сообщения
6 373
Благодарностей
3 297
Баллы
113
А если не глобал задавать а просто
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);
 

luk911

Client
Регистрация
17.01.2013
Сообщения
1 542
Благодарностей
579
Баллы
113
А тут уже проблема, что вам придётся (зачем-то) создавать объект класса CommonCode и где-то его хранить.
Я не понял при чем здесь CommonCode и где его хранить надо ....

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

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
742
Баллы
113

Mikhail B.

Moderator
Регистрация
23.12.2014
Сообщения
14 328
Благодарностей
5 431
Баллы
113
  • Спасибо
Реакции: dmitlife и Roman48

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
742
Баллы
113

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
742
Баллы
113
Что то не то, вроде работает, но что-то не так.
Ставлю этот сниппет проверяю, 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 "Нет";
 

Mikhail B.

Moderator
Регистрация
23.12.2014
Сообщения
14 328
Благодарностей
5 431
Баллы
113

Roman48

Client
Регистрация
28.02.2016
Сообщения
2 058
Благодарностей
742
Баллы
113
хз)) Вроде да, по успеху будет 60% идти.

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

Mikhail B.

Moderator
Регистрация
23.12.2014
Сообщения
14 328
Благодарностей
5 431
Баллы
113
Работает, но как то не так, если сделать 50 на 50 должно через раз, быть да и нет, а он этого не делает.
С чего ты взял)) Так не должно быть. Это вероятность, ее нельзя предсказать. Снипет работает, проверил.
Я хотел очередность, куда идти в процентах устанавливать.
Если надо очередность, то это совсем другая задача.
 

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