如何在保持最小值的同时缩放值数组?

时间:2014-06-03 23:00:58

标签: javascript arrays algorithm math

所以我有一个值数组,我需要缩小,同时保持缩放值的最小值。

例如,假设我有一组值[1, 1, 3, 5],其最小比例因子为.2

通过规范化数组,我们得到数组[.1, .1, .3, .5]。但是,请记住最小比例因子,我们的值为[.2, .2, .3, .5],最多为1.2,而不是1

我的想法是遍历数组并首先将所有低于最小值的值设置为最小值,保持进位变量以确定还需要将多少重新分配给数组中的其他元素。最小。

如果所有值都超过最小值,则相对于进位变量缩放它们的值,然后从它们的值中减去它们。

因此,通过上面的示例,我们会从3/8 * .2中减去.3,从5/8 * .2减去.5以获得[.2, .2, .225, .375]

还有其他方法可以更有效地完成这项工作吗?或者另一种扩展剩余价值的方法?


编辑:对不起,缩放可能是不正确的术语,但最后要对数组的值进行划分,使其值相对于总值进行更改。

我将解释具体实施,以便问题可能更清楚:

我有很多帖子,每个帖子都会在淡出之前显示一段时间,之后会显示下一篇文章。我希望帖子之间的延迟取决于每个帖子中单词的数量,但也要限制为至少某个最小值。

要显示的所有帖子都有总时间,并且应该在所有帖子之间分配时间。

4 个答案:

答案 0 :(得分:1)

  

我希望帖子之间的延迟取决于每个帖子中的字数,但也要限制为至少某个最小值。

     

所有帖子都有显示的总时间,应该在所有帖子之间分配时间。

您无法保证满足这两项要求。如果您有30个帖子,每个帖子必须至少显示一秒钟,并且只显示20秒,那么不可能符合这两个要求。你必须:

  1. 延长总时间; OR
  2. 缩短最短时间

答案 1 :(得分:1)

我们有一个样本集s = [ 1 1 3 5 ],我们正在寻找一个函数f(x),它只需一个样本并返回显示时间。

要求Sum(Map(s, f)) = 1.0,(即所有s [i]的f(s)之和)以及所有s[i] >= minVal的{​​{1}},首先考虑线性函数< / p>

s[i]

最低

f(x) = ax + b

和:

a.xmin + b = minVal
b = minVal - a.xmin

Substit

total = Sum(f(x) for x in s)
      = Sum((a*x + b) for x in s)
      = b*len(s) + Sum(a*x for x in s)
      = b*len(s) + a * Sum(s)
1 = b*len(s) + a * Sum(s)
a = (b * len(s) - 1.0) / Sum(s)

给出一个,

1 = b*len(s) + a * Sum(s)
1 = (minVal - a.xmin) * len(s) + a * Sum(s)
1 = minVal * len(s) - xmin * len(s) * a + Sum(s) * a
1 - (minVal * len(s)) = (Sum(s) - xmin*len(s)) * a
a = (1 - (minVal * len(s))) / (Sum(s) - xmin*len(s))

因此在javascript中我们可以有一个函数工厂来给你一个缩放函数f,给定一个样本集s:

b = minVal - a.xmin    

并在使用中:

function makeScalingFun(s, minVal) {
   var total = s.reduce(function(a, b) { return a + b; });
   var xmin = s.reduce(function(a, b) { return Math.min(a,b); });
   // f(x) = ax + b
   var a = (1.0 - (minVal * s.length)) / (total - xmin * s.length)
   var b = minVal - a * xmin
   var f = function(x) {
      return a * x + b;
   };
   return f;
}

结果:

var scaler = makeScalingFun(s, 0.2);
console.log("Index, Value: Calced Delay");
for(var i = 0; i < s.length; ++i) {
    console.log(i + ", " + s[i] + ": " + scaler(s[i]));
}

如果您有其他要求,可以使用它们构建二次目标函数而不是线性函数等。

请注意,最小值总是得到minVal延迟,这可能不太现实。考虑修改为xmin使用常量值,例如0,所以如果你有450个,451和452的3个帖子,你不会因为它是最短的而得到第一个相对较小的延迟。

答案 2 :(得分:0)

我会采取以下方法:

假设您拥有示例中的值:[1 1 3 5]。值的总和为10

因此,将所有值除以10并更正最小值。跟踪校正值的数量。在这种情况下,2。将2乘以.2。那是.4

现在,1 - .4 = .6应该分为值3535的总和为8。因此,将每个未经修正的原始值除以8并将其乘以.6:例如: 3 / 8 * .6

这将为您提供标准化的值列表:[.2 .2 .225 .375]

答案 3 :(得分:0)

显然,你无法按照通常的意义来扩展术语,因为最终时间可能会少于你的最短时间。如果帖子数量*最短时间超过您的总可用时间,您也会遇到麻烦。

但假设不是......我建议给每个帖子提供最短时间加上与较长文档中额外单词数量成比例的额外时间。因此,给定值[1 1 3 5]并且要求最小值为0.2 ...

1) Subtract the minimum value from each value to give [0 0 2 4]
2) Normalize this to give [0 0 0.333 0.667]
3) Scale by (1 - 4*0.2) (that is 1 - number_of_values*min_time) to give [0 0 0.0667 0.133333]
4) Finally add the minimum to each value to give [0.2 0.2 0.267 0.333]

现在每个帖子都会获得一个基准时间加上与其额外长度成比例的额外时间。