Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.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#_Random_Distribution - Fatal编程技术网

C# 将数量分配到桶中-不均匀

C# 将数量分配到桶中-不均匀,c#,random,distribution,C#,Random,Distribution,我一直在四处寻找解决方案,但我认为,由于我的想法,我的搜索短语可能有点倾向于不完全相关的主题 我有一个号码,比如950000。这表示整个系统中[widgets]的清单。我有大约200个“bucket”,每个bucket都应该收到这个清单的一部分,这样就不会有剩余的小部件了 我希望每个桶都能收到不同的金额。我现在没有任何可靠的代码可以展示,但这里有一些pesudo代码来说明我的想法: //List<BucketObject> _buckets is a collection of "b

我一直在四处寻找解决方案,但我认为,由于我的想法,我的搜索短语可能有点倾向于不完全相关的主题

我有一个号码,比如950000。这表示整个系统中[widgets]的清单。我有大约200个“bucket”,每个bucket都应该收到这个清单的一部分,这样就不会有剩余的小部件了

我希望每个桶都能收到不同的金额。我现在没有任何可靠的代码可以展示,但这里有一些pesudo代码来说明我的想法:

//List<BucketObject> _buckets is a collection of "buckets", each of which has a "quantity" property for holding these numbers.

int _widgetCnt = 950000;
int _bucketCnt = _buckets.Count;     //LINQ
//To start, each bucket receives (_widgetCnt / _bucketCnt) or 4750.

for (int _b = 0; b< _bucketCnt - 1; i++)
{
     int _rndAmt = _rnd.Next(1, _buckets[i].Quantity/2); //Take SOME from this bucket...
     int _rndBucket = _rnd.Next(0,_bucketCnt - 1);    //Get a random bucket index from the List<BucketObject> collection.

     _buckets.ElementAt(_rndBucket).Quantity += _rndAmt;
     _buckets.ElementAt(i).Quantity -= _rndAmt;
}
//List\u bucket是“bucket”的集合,每个bucket都有一个“quantity”属性来保存这些数字。
int_widgetCnt=950000;
int _bucketCnt=_bucket.Count//林克
//首先,每个bucket接收(_widgetCnt/_bucketCnt)或4750。
对于(int_b=0;b<_bucketCnt-1;i++)
{
int _rndAmt=_rnd.Next(1,_bucket[i].Quantity/2);//从这个bucket中取出一些。。。
int _rndBucket=_rnd.Next(0,_bucketCnt-1);//从列表集合中获取一个随机的bucket索引。
_bucket.ElementAt(_rndBucket).Quantity+=\u rndAmt;
_桶。元素(i)。数量-=\n数量;
}
这是一种统计/数学上正确的方法来处理这个问题,还是有一个分布公式来处理这个问题?更重要的是,虽然这个伪代码将运行200次(因此每个bucket都有机会改变它的数量),但它必须运行X次,这取决于小部件的类型(目前只有11种风格,但预计将来会显著扩展)

{EDIT}
该系统用于商品交易游戏。200家商店的数量必须不同,因为库存将决定该站的价格。发行版不可能是均匀的,因为这会使所有的价格相同。随着时间的推移,价格自然会失去平衡,但库存必须从平衡开始。而且所有库存的范围必须至少相似(即,没有一家商店可以有一件商品,另一家商店可以有900000件)

当然,有一个解决方案。你可以用它来完成这样的任务。分布的性质是

<席米X= 1

因此,解决方案是从Dirichlet中抽取200个(等于桶数)随机值,然后将每个值乘以950000(或任何库存总量),这将得到每个桶的项目数。如果需要非均匀采样,可以在Dirichlet采样中调整
alpha

当然,每个桶的物品都应该向上/向下取整,但这是非常琐碎的

我在C#的某个地方有Dirichlet采样,如果你很难实现它-告诉我,我会把它挖出来

更新

我发现了一些代码,.NETCore2,下面是摘录。我曾经用sample
alpha
s对Dirichlet RNs进行采样,使它们都不同是很简单的

//
// Dirichlet sampling, using Gamma sampling from Math .NET
//

using MathNet.Numerics.Distributions;
using MathNet.Numerics.Random;

static void SampleDirichlet(double alpha, double[] rn)
{
    if (rn == null)
        throw new ArgumentException("SampleDirichlet:: Results placeholder is null");

    if (alpha <= 0.0)
        throw new ArgumentException($"SampleDirichlet:: alpha {alpha} is non-positive");

    int n = rn.Length;
    if (n == 0)
        throw new ArgumentException("SampleDirichlet:: Results placeholder is of zero size");

    var gamma = new Gamma(alpha, 1.0);

    double sum = 0.0;
    for(int k = 0; k != n; ++k) {
        double v = gamma.Sample();
        sum  += v;
        rn[k] = v;
    }

    if (sum <= 0.0)
        throw new ApplicationException($"SampleDirichlet:: sum {sum} is non-positive");

    // normalize
    sum = 1.0 / sum;
    for(int k = 0; k != n; ++k) {
        rn[k] *= sum;
    }
}
//
//Dirichlet采样,使用Math.NET中的Gamma采样
//
使用MathNet.Numerics.Distributions;
使用MathNet.Numerics.Random;
静态空洞样本Dirichlet(双alpha,双[]rn)
{
如果(rn==null)
抛出新ArgumentException(“SampleDirichlet::Results占位符为null”);

如果(alpha)这是一个商品交易游戏,这是一个初始的种子方法,用于将商品数量分配给游戏世界中的不同商店。我不希望数量相等,因为商店中商品的数量决定价格;如果所有价格都相同,那么在一个港口购买/出售商品与在其他港口购买/出售商品没有区别因此,将一件物品放在第一个桶中,两件物品放在第二个桶中,依此类推,直到最后一个桶中,你将所有剩余的物品都放在其中。这满足了你的要求……我计划在数字混乱后,在后台进行更多有针对性的模拟,除了玩家活动之外,以确保玩家不会总是有这样的活动一个单一的,静态的交易路线,他们之间反弹,使成团的现金。我只需要让这些数字混乱的第一次开始的事情。我知道我会屠宰这可怕的,所以提前道歉…但使用Dirichlet与200桶将产生一系列的值之间的0和1(每个代表200桶集合中的一个桶),这些值将代表总数950000的百分比,因此(大致)200桶中的数量之和是950000…?诚然,我能找到的关于Dirichlet的信息比我习惯的要多得多:D@ChrisSmith
对200个bucket使用Dirichlet将产生一系列介于0和1之间的值(每个值表示200个bucket集合中的单个bucket),这些值将代表总数950000的百分比,因此(大致)200个桶中的数量之和是950000…?
绝对正确。它会自动正确地求和。太好了!我会尝试一下。谢谢!