在C#中实现“百分比机会”

问题描述 投票:0回答:5

我需要一些有关 C# 代码中百分比机会的帮助。假设我有一个从 1 到 100 的 for 循环,在该循环中我有一个“if”代码,我想执行 70% 次(随机)。我将如何实现这一目标?所以像这样:

static void Main(string[] args)
{
    var clickPercentage = 70;

    for (int i = 0; i < 100; i++)
    {
        if (chance)
        {
            //do 70% times
        }
    }
}

因此,对于上面的示例,我希望代码被命中的几率为 70%,对于我的示例来说大约是 70 次。

我尝试过的事情:(远低于 70%,更像是 1% 或 2% 的机会)

static void Main(string[] args)
{
    var clickPercentage = 70;

    for (int i = 0; i < 100; i++)
    {
        var a = GetRadnomNumber(1, clickPercentage);
        var b = GetRadnomNumber(1, 101);

        if (a <= b)
        {
            Console.WriteLine($"Iteracija {i} - {b} <= {a}");
        }
    }
}

public static int GetRadnomNumber(int min, int max)
{
    var random = new Random();
    var retVal = random.Next(min, max);

    return retVal;
}
c# asp.net random
5个回答
10
投票

使用

Random

您可以使用

Random.Next(100)
获得 0 到 99 之间的随机
int

public static Random RandomGen = new Random();
.....

int clickPercentage = 70;
for (int i = 0; i < 100; i++)
{
    int randomValueBetween0And99 = RandomGen.Next(100);
    if (randomValueBetween0And99 < clickPercentage)
    {
        //do 70% times
    }
}

重要的是您不要在循环中创建随机实例,因为它的默认构造函数使用当前时间作为种子。这可能会导致循环中出现重复值。这就是我使用

static
字段的原因。您还可以将
Random
实例传递给方法,以确保调用者对生命周期和种子负责。有时使用相同的种子很重要,例如重复相同的测试。


5
投票

将其包装为函数:

private static Random generator = null; 

/*
 *  Calls onSuccess() chanceOfSuccess% of the time, otherwise calls onFailure() 
 */
public void SplitAtRandom(int chanceOfSuccess, Action onSuccess, Action onFailure)
{
    // Seed
    if (generator == null)
        generator = new Random(DateTime.Now.Millisecond);

    // By chance
    if (generator.Next(100) < chanceOfSuccess)
    {
        if (onSuccess != null)
            onSuccess();
    }
    else
    {
        if (onFailure != null)
            onFailure();
    }
}

并使用它:

for (int i = 0; i < 100; i++)
{
    SplitAtRandom(70, 
                  () => { /* 70% of the time */ }, 
                  () => { /* 30% of the time */ });
} 

2
投票

不太确定你的逻辑,但快速浏览一下,你正在循环中创建一个随机对象。

问题在于

Random
类使用当前时间作为种子。如果种子相同,
Random
类将产生相同的随机数序列。由于现在的 CPU 速度非常快,通常会发生多次循环迭代具有完全相同的种子,因此随机数生成器的输出将是完全可预测的(并且与之前的输出相同)。

为了避免这种情况,只需创建一次

Random
类的实例并在代码中重用它,例如

private static readonly Random _rnd = new Random();
// use _rnd in you code and don't create any other new Random() instances

0
投票

基本上你不需要每次迭代都需要一个新的

Random
实例。简单使用这个:

var r = new Random();

for(int i = 0; i < 100; i++)
{
    var p = r.Next(100);
    if (p >= 1 - myThreshhold) // do anything in 70% of cases
}

您也可以使用

if (p <= myThreshold)


0
投票

我最近也遇到这个问题

int RF = 1;
int RV = 10;
float chance = (rand.Next(1, (RF + 1)) <= RV) ? 1 : 0;
Console.WriteLine(chance);

这是一个小决定,需要概率场和所需的值,在这种情况下你可以插入7和10,会有7到10的机会

© www.soinside.com 2019 - 2024. All rights reserved.