增加从数组中选择名称的几率
本文关键字:几率 选择 数组 增加 | 更新日期: 2023-09-27 18:21:55
对于我的程序,我已经提示用户将20个名称放入一个数组中(目前测试的数组大小为5),然后将此数组发送到一个文本文档中。我需要制作它,这样它就会从列表中随机选择一个名字并显示它(我已经这样做了)。但我现在需要让它增加名字被选中的机会,我该怎么做?
例如。我想增加从数组中选择"Jim"这个名字的机会。
class Programt
{
static void readFile()
{
}
static void Main(string[] args)
{
string winner;
string file = @"C:'names.txt";
string[] classNames = new string[5];
Random RandString = new Random();
Console.ForegroundColor = ConsoleColor.White;
if (File.Exists(file))
{
Console.WriteLine("Names in the text document are: ");
foreach (var displayFile in File.ReadAllLines(file))
Console.WriteLine(displayFile);
Console.ReadKey();
}
else
{
Console.WriteLine("Please enter 5 names:");
for (int i = 0; i < 5; i++)
classNames[i] = Console.ReadLine();
File.Create(file).Close();
File.WriteAllLines(file, classNames);
Console.WriteLine("Writing names to file...");
winner = classNames[RandString.Next(0, classNames.Length)];
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("'nThe winner of the randomiser is: {0} Congratulations! ", winner);
Thread.Sleep(3000);
Console.Write("Completed");
Thread.Sleep(1000);
}
}
}
有两种方法。您可以生成一个以一个数字为目标的正态分布的RNG。
或者更简单的方法是平移步骤。在0-100范围内生成,然后生成以有偏差的方式转换为答案的代码,例如
- 0-5:答案1
- 6-10:答案2
- 11-90:答案3
- 91-95:答案4
- 96-100:答案5
这就有80%的机会选择答案3,其他人只有5%的机会选择
因此,在当前有RandString.Next(0, classNames.Length)
的情况下,可以用类似GetBiasedIndex(0, classNames.Length, 3)
的函数来替换它
该函数看起来像这样(带有测试代码):
public Form1()
{
InitializeComponent();
int[] results = new int[5];
Random RandString = new Random();
for (int i = 0; i < 1000; i++)
{
var output = GetBiasedIndex(RandString, 0, 4, 3);
results[output]++;
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 5; i++)
{
builder.AppendLine(results[i].ToString());
}
label1.Text = builder.ToString();
}
private int GetBiasedIndex(Random rng, int start, int end, int target)
{
//Number between 0 and 100 (Helps to think percentage)
var check = rng.Next(0, 100);
//There's a few ways to do this next bit, but I'll try to keep it simple
//Allocate x% to the target and split the remaining y% among all the others
int x = 80;//80% chance of target
int remaining = 100 - x;//20% chance of something else
//Take the check for the target out of the last x% (we can take it out of any x% chunk but this makes it simpler
if (check > (100 - x))
{
return target;
}
else
{
//20% left if there's 4 names remaining that's 5% each
var perOther = (100 - x) / ((end - start) - 1);
//result is now in the range 0..4
var result = check / perOther;
//avoid hitting the target in this section
if (result >= target)
{
//adjust the index we are returning since we have already accounted for the target
result++;
}
//return the index;
return result;
}
}
输出:
52
68
55
786
39
如果你要重复调用这个函数,你需要传入RNG的实例,这样你就不会在每次调用时重置种子。
如果你想以一个名称而不是索引为目标,你只需要首先查找该名称,并在找不到该名称时有一个else条件。