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

PROforum

Client
Joined
Aug 17, 2014
Messages
252
Reaction score
19
Points
18
Здравствуйте. Подскажите как сделать на с#. Чтоб случайный ответ "ДА" выпадал с 20 % вероятностью ( "НЕТ" соответственно с 80%) и записывался в переменную проекта.
 

molotok

Client
Joined
Apr 17, 2015
Messages
743
Reaction score
366
Points
63
Если просто и на кубиках:
- создать список на десять строк, где ДА 2 шт., а НЕТ 3 шт.
- брать рандомно

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

Voronin

Client
Joined
Sep 30, 2019
Messages
76
Reaction score
54
Points
18
как-то так:

C#:
int r = Global.Classes.rnd.Next(0,99);
if (r<20)
{
    // меньше 20%
}
else
{
    // больше 20%
}
 
  • Thank you
Reactions: PROforum

Alexmd

Client
Joined
Dec 10, 2018
Messages
1,021
Reaction score
1,427
Points
113

Yuriy Zymlex

Moderator
Staff member
Joined
Oct 24, 2016
Messages
6,572
Reaction score
3,396
Points
113
Last edited:

nicanil

Client
Joined
Mar 6, 2016
Messages
2,246
Reaction score
1,828
Points
113

Yuriy Zymlex

Moderator
Staff member
Joined
Oct 24, 2016
Messages
6,572
Reaction score
3,396
Points
113
Почему?
Это глобальный рандом, его использует постер. Нужна синхронизация с ним.
 
Last edited:
  • Thank you
Reactions: JurgenZolle

nicanil

Client
Joined
Mar 6, 2016
Messages
2,246
Reaction score
1,828
Points
113
Это глобальный рандом, его использует постер.
Когда мы работаем со списком\таблицей мы лочим, чтоб несколько потоков не взяли одну и ту же строку.
Моё типичное поведение следующее: если код вносит изменения во внешнем источнике и с этим источником будет работать несколько потоков, тогда участок кода, который вносит изменения, оборачивается lock'ом; если же код только берёт данные, без какой-либо их модификации, то я и не лочу такой код.

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

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

Yuriy Zymlex

Moderator
Staff member
Joined
Oct 24, 2016
Messages
6,572
Reaction score
3,396
Points
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
Joined
Jan 17, 2013
Messages
1,542
Reaction score
579
Points
113
Конечно, не каждый это знает, но Random не потокобезопасен и его использование в шаблоне сопряжено с риском просто "сломать" этот объект,
что приведёт к дублированию результатов или утечке памяти или просто вылету постера.

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

Yuriy Zymlex

Moderator
Staff member
Joined
Oct 24, 2016
Messages
6,572
Reaction score
3,396
Points
113
а другой вариант есть ?
Создавайте в общем коде свой Random для каждого потока:
C#:
new Random(Guid.NewGuid().GetHashCode())
 
  • Thank you
Reactions: LaGir and Roman48

Roman48

Client
Joined
Feb 28, 2016
Messages
2,058
Reaction score
746
Points
113
Создавайте в общем коде свой Random для каждого потока:
C#:
new Random(Guid.NewGuid().GetHashCode())
Это как именно, яснее можно?Чтоб не опытный чел понял
 

Yuriy Zymlex

Moderator
Staff member
Joined
Oct 24, 2016
Messages
6,572
Reaction score
3,396
Points
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");
}
if(r.Next(1,100) < 20)
int r = Global.Classes.rnd.Next(0,99); if (r<20)
Помню задавался подобным вопросом и такие примеры не советовали использовать, из-за их не особой рандомности.
Советовали сравнивать с double (между 0.0 и 1.0).
 
  • Thank you
Reactions: one and Roman48

Vvafel

Client
Joined
Dec 24, 2017
Messages
80
Reaction score
35
Points
18
Вы также можете использовать:
project.Variables["result"].Value = Macros.TextProcessing.Spintax("{YES|YES|NO|NO|NO|NO|NO|NO|NO|NO}", false);
 

one

Client
Joined
Sep 22, 2015
Messages
6,851
Reaction score
1,277
Points
113
Вы также можете использовать:
project.Variables["result"].Value = Macros.TextProcessing.Spintax("{YES|YES|NO|NO|NO|NO|NO|NO|NO|NO}", false);
Последнее false что означает? И как процентуально по спинтаксу результат будет выпадать?
 

zarufakis

Client
Joined
Mar 22, 2019
Messages
1,817
Reaction score
1,204
Points
113

Vvafel

Client
Joined
Dec 24, 2017
Messages
80
Reaction score
35
Points
18
И как процентуально по спинтаксу результат будет выпадать?
60485
 
  • Thank you
Reactions: one

Moadip

Client
Joined
Sep 26, 2015
Messages
509
Reaction score
824
Points
93
Помню задавался подобным вопросом и такие примеры не советовали использовать, из-за их не особой рандомности.
Советовали сравнивать с double (между 0.0 и 1.0).
Можно юзать класс, который используется в криптографии, для генерации случайного числа. Это если начинать уже маньячить.:D
RNGCryptoServiceProvider
 

luk911

Client
Joined
Jan 17, 2013
Messages
1,542
Reaction score
579
Points
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
Joined
Aug 23, 2018
Messages
159
Reaction score
93
Points
28
А если не глобал задавать а просто
var rnd = new Random();
тоже лок надо ?
тоже интересует.
 

Yuriy Zymlex

Moderator
Staff member
Joined
Oct 24, 2016
Messages
6,572
Reaction score
3,396
Points
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
Joined
Jan 17, 2013
Messages
1,542
Reaction score
579
Points
113
А тут уже проблема, что вам придётся (зачем-то) создавать объект класса CommonCode и где-то его хранить.
Я не понял при чем здесь CommonCode и где его хранить надо ....

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

Roman48

Client
Joined
Feb 28, 2016
Messages
2,058
Reaction score
746
Points
113
C#:
Random r = new Random();
if(r.Next(1,100) < 20) return "Да";
else return "Нет";
Как в этот код переменную вставить, вместо 20?
 

Mikhail B.

Client
Joined
Dec 23, 2014
Messages
14,453
Reaction score
5,472
Points
113

Обращаем Ваше внимание на то, что данный пользователь заблокирован.
Не рекомендуем проводить с Mikhail B. какие-либо сделки.

Как в этот код переменную вставить, вместо 20?
C#:
int i = int.Parse(project.Variables["pr"].Value);
Random r = new Random();
if(r.Next(1,100) < i) return "Да";
else return "Нет";
 

Roman48

Client
Joined
Feb 28, 2016
Messages
2,058
Reaction score
746
Points
113
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% будет да или нет?
 

Roman48

Client
Joined
Feb 28, 2016
Messages
2,058
Reaction score
746
Points
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.

Client
Joined
Dec 23, 2014
Messages
14,453
Reaction score
5,472
Points
113

Обращаем Ваше внимание на то, что данный пользователь заблокирован.
Не рекомендуем проводить с Mikhail B. какие-либо сделки.

Если в переменной pr будет цира 60 то 60% будет да или нет?
хз)) Вроде да, по успеху будет 60% идти.
Что то не то, вроде работает, но что-то не так.
Да он не работает, щас проверю еще раз.
 

Roman48

Client
Joined
Feb 28, 2016
Messages
2,058
Reaction score
746
Points
113
хз)) Вроде да, по успеху будет 60% идти.

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

Mikhail B.

Client
Joined
Dec 23, 2014
Messages
14,453
Reaction score
5,472
Points
113

Обращаем Ваше внимание на то, что данный пользователь заблокирован.
Не рекомендуем проводить с Mikhail B. какие-либо сделки.

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

Users Who Are Viewing This Thread (Total: 0, Members: 0, Guests: 0)