[英]How can I scale an array of values while maintaining a minimum value?
因此,我有一個值數組,我需要按比例縮小該值,同時保持該值的最小值。
例如,假設我有一個值數組[1, 1, 3, 5]
,其最小比例因子為.2
。
通過規范化數組,我們得到數組[.1, .1, .3, .5]
。 但是,請記住最小比例因子,我們將得到[.2, .2, .3, .5]
,它們的總和為1.2
,而不是1
。
我的想法是遍歷數組,首先將所有低於最小值的值設置為最小值,保留一個進位變量,以確定仍然需要將多少重新分配給數組中超過最小值的其他元素。
在所有值都超過最小值的情況下,相對於進位變量縮放其值,然后從其值中減去該值。
因此,在上面的示例中,我們從.3
減去3/8 * .2
,從.5
減去5/8 * .2
得到[.2, .2, .225, .375]
。
還有其他方法可以更有效地做到這一點嗎? 或其他方法來縮放剩余值?
編輯:對不起,縮放可能是錯誤的術語,但是最后將數組的值進行划分,以使它們的值相對於總值發生變化。
我將解釋具體的實現,以便使問題更明確:
我有很多帖子,在淡出之前,每個帖子都會顯示一段時間,然后顯示下一個帖子。 我希望帖子之間的延遲取決於每個帖子中的單詞數,但也應至少限制為一些最小值。
顯示所有帖子的時間總計 ,應該在所有帖子之間分配時間。
我希望帖子之間的延遲取決於每個帖子中的單詞數,但也應至少限制為一些最小值。
顯示所有帖子的時間總計,應該在所有帖子之間分配時間。
您不能保證同時滿足這兩個要求。 如果您有30個帖子,每個帖子必須至少顯示一秒鍾,並且僅顯示20秒鍾,那么就不可能同時滿足這兩個要求。 您必須:
我們有一個樣本集s = [ 1 1 3 5 ]
,並且我們正在尋找一個函數f(x)
,該函數需要一個樣本並返回顯示時間。
需要Sum(Map(s, f)) = 1.0
,(即,F(S)的所有S的總和[I]),而且s[i] >= minVal
對於所有s[i]
首先考慮線性函數
f(x) = ax + b
最低限度
a.xmin + b = minVal
b = minVal - a.xmin
和:
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)
Substit
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))
給定一個,
b = minVal - a.xmin
因此,在javascript中,如果提供了樣本集s,我們可以有一個函數工廠為您提供縮放函數f:
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]));
}
結果:
Index, Value: Calced Delay
0, 1: 0.2
1, 1: 0.2
2, 3: 0.26666666666666666
3, 5: 0.3333333333333333
如果您還有其他要求,可以使用它們來構造二次目標函數,而不是線性目標函數,等等。
請注意,最小值總是在給定minVal延遲的情況下獲得,這可能不太現實。 考慮修改以使用xmin的恆定值(例如0),這樣,如果您有3個帖子,分別為450、451和452,您就不會因為第一個帖子的延遲最短而僅獲得相對較小的延遲。
我將采用以下方法:
假設您具有示例中的值: [1 1 3 5]
。 值的總和為10
。
因此,將所有值除以10
並校正最小值以下的值。 跟蹤校正值的數量。 在這種情況下為2
。 將2
乘以.2
。 那是.4
。
現在,應將1 - .4 = .6
除以值3
和5
。 3
和5
的總和是8
。 因此,將每個未校正的原始值除以8
然后乘以.6
:例如3 / 8 * .6
。
這將為您提供標准化的值列表: [.2 .2 .225 .375]
。
顯然,您無法按單詞的通常含義來擴展術語,因為最終的時間可能少於最小時間。 如果帖子數*最短時間超過了您的總可用時間,您也會遇到麻煩。
但是假設不...我建議給每個帖子最少的時間,再加上與較長文檔中多余單詞數成正比的額外時間。 因此,給定值[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]
現在,每個帖子都會獲得一個基准時間,再加上一個與其額外長度成比例的額外時間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.