所以我正在为一个侧面项目写作并尝试优化:
给定一组n个数(例如[4,10,15,25,3]),我们希望在给定的容差范围内使每个数字大致相同(即如果我们想要精确,那么它应该是11.4)在上面的例子中)。
我们可以添加/删除一个并添加到另一个。例如,我们可以从[3]和+5到[1],这将给我们[9,10,10,25,3]。
我所拥有的约束是我们想要最少数量的"转移"在每个数字之间(例如,如果我们从[3]做-3.6,那么它算作一个"转移")。
没有关于性能的讨论(大多数我可以看到它最多只有一组50个数字)但是真的希望将传输保持在最低限度。
我们可以假设容差为+/- 1,但可以动态改变。
答案 0 :(得分:0)
在代码中,getMinMax函数足够简单,返回最小/最大值,索引和距离(减法的绝对值)
// the principle of the balance is to even the most different numbers in the set (min and max)
const balance = (threshold, arr) => {
const toBalance = Object.assign([], arr);
let mm = getMinMax(toBalance);
while (mm.distance > threshold){
toBalance[mm.maxIdx] -= mm.distance / 2;
toBalance[mm.minIdx] += mm.distance / 2;
mm = getMinMax(toBalance);
}
return toBalance;
}
测试它
const numbers = [4, 10, 15, 25, 3];
const threshold = 0;
const output = balance(threshold, numbers);
console.log(output);
// prints an array with four numbers of 11.4 (with some precision error)
答案 1 :(得分:0)
算法的目标是确保列表中的每个数字在给定的容差范围内大致相同。因此,如果容差为零,则所有数字必须等于列表中所有值的平均值(在整个算法中将保持不变)。考虑到容差,列表中的所有数字都必须属于包含间隔[average - 0.5*TOLERANCE, average + 0.5*TOLERANCE]
。
算法的主要迭代包括检索最大值和最小值,并从最大值到最小值“转移”,使得最远的值(这可能是最小值)或最大值落在所需的时间间隔内。此过程将迭代,直到最大值和最小值彼此相距不超过TOLERANCE
个单位。
算法的伪代码如下所示:
target = average of the values in the list
while dist(max, min) > TOLERANCE
x = maximum of dist(max, target) and dist(min, target)
transfer (x - 0.5*TOLERANCE) units from maximum into minimum
dist(a, b)
可以简单地定义为abs(a - b)
此算法平均运行时间约为O(n^2)
,需要的时间超过n
次,其中n
是值的数量。
这种算法所需的迭代次数不到一半,这种简单的次优方法只能平均每次迭代中的最小值和最大值。