名字的几率增加从Array被采摘 [英] Increase chances of name being picked from Array

查看:75
本文介绍了名字的几率增加从Array被采摘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关我的计划,我已经提示用户把20名到一个数组(数组大小为5的测试现在),这个数组然后被发送到一个文本文件。我需要它,这样它会随机从列表中选择一个名字,并显示它(我做了)。不过,我现在需要使它增加被起名字的机会,我怎么会去这样做?

例如。我想增加名字吉姆的机会从阵列被拾起。

 类Programt
{
    静态无效ReadFile的()
    {
    }    静态无效的主要(字串[] args)
    {
        字符串的赢家;
        字符串文件= @C:\\ names.txt中;
        字符串[] =类名新的字符串[5];
        随机RandString =新的随机();
        Console.ForegroundColor = ConsoleColor.White;
        如果(File.Exists(文件))
        {
            Console.WriteLine(文本文件的名称是:);
            的foreach(在File.ReadAllLines变种displayFile(文件))
            Console.WriteLine(displayFile);
            Console.ReadKey();
        }
        其他
        {            Console.WriteLine(请输入姓名5);
            的for(int i = 0;我小于5;我++)
                类名由[i] =到Console.ReadLine();
            File.Create(文件).Close();
            File.WriteAllLines(文件,类名);
            Console.WriteLine(写名到文件...);
            赢家=类名[RandString.Next(0,classNames.Length)];
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine(下称随机化的\\ n该得主是:{0}恭喜!获得者);
            Thread.sleep代码(3000);
            Console.Write(已完成);
            Thread.sleep代码(1000);
        }
    }
}


解决方案

有这样做的两种方式。您可以产生RNG用正态分布针对一个号码。

还是简单的方法是平移的一步。生成0到100之间,然后产生code,转换为答案在偏见的方式例如


  • 0-5:回答1

  • 6-10:答2

  • 11-90:答案3

  • 91-95:答案4

  • 96-100:回答5

这给出了答案采摘3的80%的机会,别人只能得到5%的几率

那么,您目前有 RandString.Next(0,classNames.Length)您可以替换,与功能类似 GetBiasedIndex(0, classNames.Length,3)

该功能会是这个样子(与测试code):

 公共Form1中()
    {
        的InitializeComponent();
        INT []结果=新INT [5];        随机RandString =新的随机();        的for(int i = 0; I< 1000;我++)
        {
            无功输出= GetBiasedIndex(RandString,0,4,3);
            结果[输出] ++;
        }
        StringBuilder的建设者=新的StringBuilder();
        的for(int i = 0;我小于5;我++)
        {
            builder.AppendLine(结果[I]的ToString());
        }
        label1.Text = builder.ToString();
    }
    私人诠释GetBiasedIndex(随机RNG,诠释开始,诠释年底,INT目标)
    {
        // 0和100之间的数字(要放眼百分比)
        VAR检查= rng.Next(0,100);
        //有几个方法可以做到这一点下位,但我会尽量保持简单
        //分配x%的目标,所有的人之间平分剩下的Y%
        INT X = 80; // 80%的目标的机会
        INT剩余= 100 - X; // 20%的其他东西的机会
        //将目标出的​​最后x%的检查(我们可以把它任何x%的块,但这样可以更容易
        如果(检查>(100 - X))
        {
            返回的目标;
        }
        其他
        {
            离开// 20%,如果有剩下的那5%每4名
            VAR perOther =(100 - X)/((结束 - 开始) - 1);
            //结果现在是在范围0..4
            VAR的结果=检查/ perOther;
            //避免撞上在本节目标
            如果(结果> =目标)
            {
                //调整,因为我们已经占了目标,我们正在返回索引
                结果++;
            }
            //返回指数;
            返回结果;
        }
    }

和输出:


  

52结果
  68结果
  55结果
  786结果
  39


如果你要反复调用此函数,你需要在RNG的实例来传递,这样你就不会重置种子每次调用。

如果你想针对一个名称,而不是你只需要先查找该名称,并有当该名称未找到一个else条件的指数

For my program, I've prompted the user to put 20 names into an array (the array size is 5 for testing for now), this array is then sent to a text document. I need to make it so that it will randomly pick a name from the list and display it (which I have done). But I now need to make it increase the chances of a name being picked, how would I go about doing this?

Eg. I want to increase the chances of the name 'Jim' being picked from the array.

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);
        }
    }
}

解决方案

There's two ways of doing this. You can either produce a RNG with a normal distribution targeting one number.

Or the simpler way is a translational step. Generate in the range 0-100 and then produce code which translates to the answer in a biased way e.g.

  • 0-5 : Answer 1
  • 6-10: Answer 2
  • 11-90: Answer 3
  • 91-95: Answer 4
  • 96-100: Answer 5

This gives an 80% chance of picking Answer 3, the others only get a 5% chance

So where you currently have RandString.Next(0, classNames.Length) you can replace that with a function something like GetBiasedIndex(0, classNames.Length, 3)

The function would look something like this (with test code):

    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;
        }
    }

and the output:

52
68
55
786
39

If you're going to call this function repeatedly you'll need to pass in the instance of the RNG so that you don't reset the seed each call.

If you want to target a name instead of an index you just need to look up that name first and have an else condition for when that name isn't found

这篇关于名字的几率增加从Array被采摘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆