【发布时间】:2012-04-28 00:42:13
【问题描述】:
我想在 double 类型的已知值数组中添加一种波纹。我指出这一点是因为 Random.Next / Random.NextDouble() 表现不同。
我怎样才能最好地完成这项任务?
假设我在数组中有 20 个值,List<double> arr = new List<double>() { 40, 40, 40, 40 ..... };
20 个值,平均 40 个,总共 800 个,以便更容易。
在这个方法之后,我希望总和仍然保持 800,但每个单独的值都应该修改。这些值应该是正数,因为它们是之后添加的total+=i。
到目前为止,这个问题是使用给定数量值的百分比来解决的。 1.0 / 20 = 0.05, then multiplicate that with the total and the iteration number. Then subtract the result from the remainder. Finally i just return a sort by new 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];
已允许最后生成的值不重叠。另外,当列表只包含两个值时例外。 qty=1 可能看起来很神奇,但它指的是对象 bArray 的真实外观。无论如何,我认为整个想法很清楚。
【问题讨论】:
-
你能随机扰动前 n-1 个值,然后使最后一个值成为所需的值,使总数达到 800?
-
@mellamokb 听起来会不成比例地扭曲最后一个值。
-
@Dr.Wily'sApprentice:确实如此,我测试过 :) 另一个想法:扰动所有的值,然后在所有数字中分散它的数量。
-
我开始考虑控制一组百分比(除以 x 数量等),但因为我开始通过火星寻找月亮的感觉而停下来...... :)
-
使用 guid 作为随机化的关键进行排序是最糟糕的做法。 Guid 保证是唯一的,不保证是随机的。 guid 生成器完全有权生成连续的 guid,有些确实如此!如果您想按随机数排序,则生成一个随机数。为工作使用正确的工具;仅当您需要唯一标识符时才生成 guid。