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

C# 获得给定值周围的随机畸变

C# 获得给定值周围的随机畸变,c#,arrays,algorithm,math,C#,Arrays,Algorithm,Math,我想向类型为double的已知值数组添加一种涟漪。我指出这一点是因为Random.Next/Random.NextDouble()的行为不同 我如何才能最好地完成这项任务 假设数组中有20个值, List arr=new List(){40,40,40,40….} 20个值,在数量40上求平均值,总数为800,以便于计算 在这个方法之后,我希望总的总数仍然保持在800,但是每个单独的值都应该被修改。这些值应为正值,因为它们是随后添加的total+=i 到目前为止,这个问题是使用给定数量的值的百分

我想向类型为double的已知值数组添加一种涟漪。我指出这一点是因为Random.Next/Random.NextDouble()的行为不同

我如何才能最好地完成这项任务

假设数组中有20个值,
List arr=new List(){40,40,40,40….}
20个值,在数量40上求平均值,总数为800,以便于计算

在这个方法之后,我希望总的总数仍然保持在800,但是每个单独的值都应该被修改。这些值应为正值,因为它们是随后添加的
total+=i

到目前为止,这个问题是使用给定数量的值的百分比来解决的
1.0/20=0.05,然后将其与总数和迭代次数相乘。然后从余数中减去结果。最后,我只返回按新Guid()排序的结果。

正如您已经看到的,这个方法只是有点了不起,而只有大约5-20个值。在我今天的例子中,这个数组需要有500-2000个值(每个值的0,2-0,05%)

相反,我想得到一个导数,或者类似的,它以值40的+-x%为基础,产生失真。或者,也许更好,数组中任何单个值的+-x%)

[更新]

我将根据对该问题的答复添加该问题的更新

    Random rnd = new Random();
    List<double> ripple = new List<double>();

    int qty = bArray.Count();
    double diff = last.Value - first.Value;

    if (qty == 1)
    {
        double linearAvg = (diff / qty) / 2;
        ripple.Add(linearAvg);
    }
    else
    {
        double[] rndarr = new double[qty];

        for (int i = 0; i < qty; i++)
            rndarr[i] = rnd.NextDouble();

        double rndArrSum = rndarr.Sum();

        for (int i = 0; i < qty; i++)
            rndarr[i] /= rndArrSum; 

        for (int i = 0; i < qty; i++)
            ripple.Add(diff * rndarr[i]);
    }

    double valueOverall = first.Value;
    for (int i = (qty > 1) ? 1 : 0; i < qty; i++)
        valueOverall += ripple[i];
Random rnd=new Random();
List ripple=新列表();
int qty=bArray.Count();
双差=最后一个值-第一个值;
如果(数量=1)
{
双线RAVG=(差异/数量)/2;
ripple.Add(linearAvg);
}
其他的
{
double[]rndarr=新的double[数量];
对于(int i=0;i1)?1:0;i

已为最后生成的值留出不重叠的余量。此外,当列表仅包含两个值时会出现异常​​.
qty=1
可能看起来很神奇,但它指的是对象bArray在实际中的样子。无论如何,我认为整个想法都很清楚。

一种方法是生成0到1之间的N个随机数(互斥)。把它们加起来。然后将每个数字除以总和。您现在有一个N个随机数的列表,这些随机数的总和为1。现在,将这些数字中的每一个乘以所需的和,得到将进入最终数组的数字


如果希望数值为+/-某个百分比,则使用
Random.Next
生成某个范围内的随机数并求和。然后除以总数,得到总和为1的数字列表。最后一步是相同的。

可以这样做的一种方法是生成0到1之间的N个随机数(互斥)。把它们加起来。然后将每个数字除以总和。您现在有一个N个随机数的列表,这些随机数的总和为1。现在,将这些数字中的每一个乘以所需的和,得到将进入最终数组的数字


如果希望数值为+/-某个百分比,则使用
Random.Next
生成某个范围内的随机数并求和。然后除以总数,得到总和为1的数字列表。最后一步是相同的。

另一种方法是通过数组循环并按百分比值进行扰动。完成后,计算出与总数的差距,并将平均分布在所有数字上的超龄金额相加。下面是一些示例代码:

var test = Enumerable.Repeat<double>(40, 100).ToArray();
var percent = 0.5d;

var rand = new Random();
var expectedTotal = test.Sum();
var currentTotal = 0d;
var numCount = test.Count();

for (var i = 0; i < numCount; i++)
{
    var num = test[i];
    var range = num * percent * 2;

    var newNum = num + (rand.NextDouble() - 0.5) * (range);
    currentTotal += newNum;
    test[i] = newNum;
}

var overage = (expectedTotal - currentTotal);

for (var i = 0; i < numCount; i++)
    test[i] += overage / numCount;
var test=Enumerable.Repeat(40100).ToArray();
风险值百分比=0.5d;
var rand=new Random();
var expectedTotal=test.Sum();
var currentTotal=0d;
var numCount=test.Count();
对于(变量i=0;i
另一种方法是在数组中循环并按百分比值进行扰动。完成后,计算出与总数的差距,并将平均分布在所有数字上的超龄金额相加。下面是一些示例代码:

var test = Enumerable.Repeat<double>(40, 100).ToArray();
var percent = 0.5d;

var rand = new Random();
var expectedTotal = test.Sum();
var currentTotal = 0d;
var numCount = test.Count();

for (var i = 0; i < numCount; i++)
{
    var num = test[i];
    var range = num * percent * 2;

    var newNum = num + (rand.NextDouble() - 0.5) * (range);
    currentTotal += newNum;
    test[i] = newNum;
}

var overage = (expectedTotal - currentTotal);

for (var i = 0; i < numCount; i++)
    test[i] += overage / numCount;
var test=Enumerable.Repeat(40100).ToArray();
风险值百分比=0.5d;
var rand=new Random();
var expectedTotal=test.Sum();
var currentTotal=0d;
var numCount=test.Count();
对于(变量i=0;i
下面是我的解决方案

基本上,它按指定的百分比“抖动”每个值,然后检查原始总数和“抖动”总数之间的差异。为了使最终总额与原始总额相匹配,它将向每个“抖动”值添加固定金额

我觉得从数学的角度来看,这不是一个很好的解决方案,因为我认为将固定数量添加到每个值中可能会扭曲每个值的真实简化百分比。可能有一种数学上更正确的方法可以在整个值集上应用余数,以保持预期的简化百分比,但我认为这样做需要几次过程,而此解决方案只需一组过程即可完成

// prepare data
double[] values = new double[20];
for (int i = 0; i < values.Length; i++)
{
    values[i] = 40.0;
}

// get the original total
double originalTotal = 0.0;
for (int i = 0; i < values.Length; i++)
{
    originalTotal += values[i];
}

// specify an abberation percentage
double x = 0.05;

// jitter each value +/- the abberation percentage
// also capture the total of the jittered values
Random rng = new Random();
double intermediateTotal = 0.0;
for (int i = 0; i < values.Length; i++)
{
    values[i] += values[i] * (rng.NextDouble() - 0.5) * (2.0 * x);
    intermediateTotal += values[i];
}

// calculate the difference between the original total and the current total
double remainder = originalTotal - intermediateTotal;

// add a flat amount to each value to make the totals match
double offset = remainder / values.Length;
for (int i = 0; i < values.Length; i++)
{
    values[i] += offset;
}

// calculate the final total to verify that it matches the original total
double finalTotal = 0.0;
for (int i = 0; i < values.Length; i++)
{
    finalTotal += values[i];
}
//准备数据
double[]值=新的double[20];
for(int i=0;i