Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将等于的随机变量C#设置为总和_C#_Algorithm_Math_Random - Fatal编程技术网

将等于的随机变量C#设置为总和

将等于的随机变量C#设置为总和,c#,algorithm,math,random,C#,Algorithm,Math,Random,我正在创建一个游戏,其中有人打开一个箱子,箱子会给他们一个随机的奖品。我能给出的最大值是10000箱中的85000000箱,这是8500箱的平均值,但是我希望一些箱子能达到这个值,因此一些箱子将低于这个值,并且高于这个值,并且能够设置最小损失2500箱,最大赢250000箱,但仍然获得85000000箱的总价值 我真的很难用我的C#知识想出一个算法来解决这个问题。伪代码算法: 使用一组箱子 数组的索引为胸数;数组的长度是箱子的数量 数组中的值是该索引处胸部的数量 初始值是总金额除以箱子数量

我正在创建一个游戏,其中有人打开一个箱子,箱子会给他们一个随机的奖品。我能给出的最大值是10000箱中的85000000箱,这是8500箱的平均值,但是我希望一些箱子能达到这个值,因此一些箱子将低于这个值,并且高于这个值,并且能够设置最小损失2500箱,最大赢250000箱,但仍然获得85000000箱的总价值

我真的很难用我的C#知识想出一个算法来解决这个问题。

伪代码算法:

  • 使用一组箱子
    • 数组的索引为胸数;数组的长度是箱子的数量
    • 数组中的值是该索引处胸部的数量
    • 初始值是总金额除以箱子数量
  • 现在重复几次(比如说:胸部数量的10倍)
    • 随机得到两个箱子
    • 计算出你可以从1号箱子转移到2号箱子的最大数量,这样1号箱子就不会低于最小值,2号箱子就不会高于最大值
    • 获取一个低于该最大值的随机值并将其传输
现在,请尝试在C#中实现此功能。

伪代码算法:

  • 使用一组箱子
    • 数组的索引为胸数;数组的长度是箱子的数量
    • 数组中的值是该索引处胸部的数量
    • 初始值是总金额除以箱子数量
  • 现在重复几次(比如说:胸部数量的10倍)
    • 随机得到两个箱子
    • 计算出你可以从1号箱子转移到2号箱子的最大数量,这样1号箱子就不会低于最小值,2号箱子就不会高于最大值
    • 获取一个低于该最大值的随机值并将其传输

现在尝试在C#中实现它。

这应该是一个很好的起点。每一个箱子都会随机填充限制,以确保剩余箱子也能获得有效值

        Random rand = new Random();
        int[] chests = new int[numOffChests];
        int remaining = TotalValue;
        for(int i = 0; i < numOffChests; i++)
        {
            int minB = Math.Max(remaining / (numOffChests - i), maxChestValue);
            int maxB = Math.Min(remaining - (numOffChests - i * minChestValue), maxChestValue);
            int val = rand.Next(minB, maxB);
            remaining -= val;
            chests[i] = val;
        }
Random rand=new Random();
int[]箱子=新的int[numofchests];
剩余整数=总值;
for(int i=0;i
这应该是一个很好的起点。每一个箱子都会随机填充限制,以确保剩余箱子也能获得有效值

        Random rand = new Random();
        int[] chests = new int[numOffChests];
        int remaining = TotalValue;
        for(int i = 0; i < numOffChests; i++)
        {
            int minB = Math.Max(remaining / (numOffChests - i), maxChestValue);
            int maxB = Math.Min(remaining - (numOffChests - i * minChestValue), maxChestValue);
            int val = rand.Next(minB, maxB);
            remaining -= val;
            chests[i] = val;
        }
Random rand=new Random();
int[]箱子=新的int[numofchests];
剩余整数=总值;
for(int i=0;i
下面是一些OOP。你有
Player
class。它存储了一些信息——他拥有的黄金数量、打开的箱子数量以及他将找到的箱子中的黄金总量

public class Player
{
    private int gold = 0;
    private int goldLeftInChests = 85000000;
    private int chestsToOpen = 10000;
    private Random random = new Random();

    public void OpenChest()
    {
        if (chestsToOpen == 0)
            return; // or whatever you want after 10000 chests.

        int goldInChest = CalculateGoldInNextChest();
        goldLeftInChests -= goldInChest;
        chestsToOpen--;
        gold += goldInChest;
    }

    private int CalculateGoldInNextChest()
    {
        if (chestsToOpen == 1)
            return goldLeftInChests;

        var average = goldLeftInChests / chestsToOpen;
        return random.Next(average);
    }
}
当下一个箱子打开时,计算箱子中的黄金,并调整玩家数据-我们向玩家添加一些黄金,减少箱子中的黄金总量,留下来打开箱子

计算箱子里的金子很简单。我们得到剩余的平均数量,并计算1和平均数之间的数字。第一次此值将始终低于8500。但下一次的平均值会大一点。所以玩家将有机会找到超过8500个。如果他再倒霉,平均数就会增加。或者,如果帕莱尔得到很多金子,它就会减少


更新:正如@Hans所指出的,我没有计算箱子里黄金的最小和最大限制。@Hans解决方案中也存在一个问题-您应该在10000箱之间移动黄金很多时间,以获得接近250000箱的价值。您必须填写并保留所有10000个值。我想的下一个问题是.NET中的随机数分布。在我们使用的所有区间上,值的概率相等。因此,如果我们创造的价值从2500到250000不等,那么我们获得8500(平均值)左右的价值的可能性就相当于12000(8500±6000)比235500(250000-12000-2500)。这意味着从给定范围生成默认随机数将在开始时为您提供大量大数字,然后您将停留在最低边界(2500)附近。所以你需要不同分布的随机数-。我们仍然希望拥有8500枚最高概率的黄金,以及250000枚最低概率的黄金。诸如此类:

最后一部分——计算。我们只需要更新一个方法:)


注意:我曾经使代码更具可读性。多次运行测试会产生超过200000的最佳值。

下面是一些OOP。你有
Player
class。它存储了一些信息——他拥有的黄金数量、打开的箱子数量以及他将找到的箱子中的黄金总量

public class Player
{
    private int gold = 0;
    private int goldLeftInChests = 85000000;
    private int chestsToOpen = 10000;
    private Random random = new Random();

    public void OpenChest()
    {
        if (chestsToOpen == 0)
            return; // or whatever you want after 10000 chests.

        int goldInChest = CalculateGoldInNextChest();
        goldLeftInChests -= goldInChest;
        chestsToOpen--;
        gold += goldInChest;
    }

    private int CalculateGoldInNextChest()
    {
        if (chestsToOpen == 1)
            return goldLeftInChests;

        var average = goldLeftInChests / chestsToOpen;
        return random.Next(average);
    }
}
当下一个箱子打开时,计算箱子中的黄金,并调整玩家数据-我们向玩家添加一些黄金,减少箱子中的黄金总量,留下来打开箱子

计算箱子里的金子很简单。我们得到剩余的平均数量,并计算1和平均数之间的数字。第一次此值将始终低于8500。但下一次的平均值会大一点。所以玩家将有机会找到超过8500个。如果他再倒霉,平均数就会增加。或者,如果帕莱尔得到很多金子,它就会减少


更新:正如@Hans所指出的,我没有计算箱子里黄金的最小和最大限制。@Hans解决方案中也存在一个问题-您应该在10000箱之间移动黄金很多时间,以获得接近250000箱的价值。您必须填写并保留所有10000个值。我想下一个问题是ab
250,000+2,500*exp(a) = c*(1-exp(a))
               8,500 = 252,500/a+c
a =  22.954545, 
b = -10.515379, 
c = -2500.00002711621
int minwin = -2500 ;
int maxwin = 250000;
int chestcount = 10000;
int maxamount  = 85000;
// ----------- get probabilities for each win/lose amount to occur in all chests  ----------
long probtotal = 0 ;
List<long> prob = new List<long> ; 
for (long i=minwin;i<=maxwin;i++) if (i%100==0) 
{ long ii=(maxwin-i)*(maxwin-i) ; prob.Add((float)ii) ; probtotal+=ii ; }
for (int i=0;i<prob.Count;i++) prob[i]=prob[i]/(probtotal) ;
for (int i=0;i<prob.Count;i++) 
  Console.writeLine("Win/lose amount"+((i-minwin)*100).ToString()+" probability="+(proba[i]*100).ToString("0.000")) ;
// Transform "prob" so as to indicate the float count of chest corresponding to each win/lose amount
for (int i=0;i<prob.Count;i++) prob[i]=prob[i]*chestcount ;

// ---------- Set the 10000 chest values starting from the highest win -------------
int chestindex=0 ;
List<int> chestvalues = new List<int>();
float remainder = 0 ;
int totalwin=0 ;
for (int i=0;i<prob.Count;i++)
{
   int n = (int)(prob[i]+remainder)  ; // only the integer part of the float ;
   remainder = prob[i]+remainder-n ;    
   // set to n chests the win/lose amount
   int curwin=(i-minwin)*100 ;
   for (int j=0;j<n && chestvalues.count<chestcount;j++) chestvalues.Add(curwin) ; 
   totalwin+=curwin ;
}
// if stvalues.count lower than chestcount, create missing chestvalues  
for (int i=chestvalues.Count;i<chestcount;i++) chestvalues.Add(0) ;

// --------------- due to float computations, we perhaps want to make some adjustments --------------
// i.e. if totalwin>maxamount (not sure if it may happen), decrease some chestvalues
...
// --------------- We have now a list of 10000 chest values to be randomly sorted --------------
Random rnd = new Random();
SortedList<int,int> randomchestvalues = new SortedList<int,int>() ;
for (int i=0;i<chestcount;i++) randomchestvalues.Add(rnd.Next(0,99999999),chestvalues[i]) ;
// display the first chests amounts
for (int i=0;i<chestcount;i++) if (i<234) 
{ int chestamount = randomchestvalues.GetByIndex(i) ; Console.WriteLine(i.ToString()+":"+chestamount) ; }
}