使用数学算法随时间增加价值

Posted

技术标签:

【中文标题】使用数学算法随时间增加价值【英文标题】:Increase value over time using mathematical algorithm 【发布时间】:2009-09-23 01:51:35 【问题描述】:

我正在编写一个测试工具,它会给网络服务带来大量负载。我希望这个工具从小负载开始,随着时间的推移逐渐增加。我确信有一些三角函数可以在一行代码中进行这种计算,但我还不是数学大师。是否有某种库(或简单算法)可以帮助进行此计算?

理想情况下,该代码需要几个参数:

要使用的算法(确定值增加的速度 起始值 结束值(最大值) 时间(开始值和结束值之间的时间量) 步长(以毫秒为单位的粒度)

因此,每个 [step] 都会引发一个事件,指示该时间点的值。

虽然这是一个理想的实现,所以我愿意接受建议。

任何意见将不胜感激,谢谢:)

编辑:

让我更清楚一点......值增加的量不是线性的,它是一条曲线。

【问题讨论】:

好的,什么曲线?你能描述一下理想曲线是什么样子的吗? 有很多曲线你可以从我的回答中选择:P 【参考方案1】:

如果您想要某种形式的饱和度(请参阅 Sigmoid function),请查看我的回答 here。另一个常见的函数形状是linear or exponential growth。如果您需要后者之一,请告诉我。

【讨论】:

听起来像 sigmoid 曲线是你要找的,像 maxVal / (1 + e^(minVal - x)) 这样的函数应该做,其中 x 是当前步骤【参考方案2】:

我认为你需要一些缓动函数。

Robert Penner 创建了一组著名的缓动函数。您可以尝试查看: Tweener transition cheat sheets 可视化 Robert Penner 的方程。

Robert Penner 的原始代码应位于 his webpage。

【讨论】:

那些备忘单显示了我正在尝试做的事情...显示大量负载配置文件并允许用户选择一个:) 谢谢:)【参考方案3】:

value = (endValue - StartValue) / (time / stepSize) * currentStep;

【讨论】:

【参考方案4】:

每次定时器关闭时添加一个

【讨论】:

【参考方案5】:

如果我理解正确,为什么不这样做(使用您定义的“变量”): 您需要提高整体结束值 - 起始值值。

使用时间变量,您可以计算出您希望每毫秒增加多少(我们称之为增加量)。

Step 只是告诉您在您提出的每个值之间“休眠”的时间。每次提出新值时,您只需 last-value + (milliseconds-since-last_step * increase-amount)

注意:我不确定您为什么需要第一个变量(要使用的算法),因为在我看来,它的作用是由其他变量定义的。

【讨论】:

查看我的问题编辑以了解第一个(“算法”)参数的解释。 那么在这种情况下,我们都必须等待有人提供解决方案,我不知道该怎么做......【参考方案6】:

你在寻找这样的东西吗? (在 python 中,对不起,我的 C# 充其量是生锈了)

假设您有一条取值从 0 到 1 的曲线 f:

def my_stepper(f, start, end, time, step_size, current_step): x = current_step * step_size / 时间 f_1 = f(1) f_0 = f(0) y = 开始 + (结束 - 开始) * (f(x)- f_0) / (f_1 - f_0) 返回 y 对于 xrange(11) 中的 i: # 增量随时间增加 打印 'exp', my_stepper(math.exp, 100., 200., 10., 1., i) # 增量随时间递减 print 'log', my_stepper(lambda x: math.log(1+x), 100., 200., 10., 1., i)

【讨论】:

【参考方案7】:

您的问题的伪逻辑:

对于给定的步骤 x,让函数为 F(a+b*x), 让起始值为start, 让结束值为 end 设开始时间为0,结束时间为时间 InverseF 是 F 的反函数。

当 x=0 时,F(a)=start 因此 a= InverseF(start) 当 x=time 时,F(a+b*time)=end,因此 b=(InverseF(end)-a)/time 减少为 b= (inverseF(end)-inverseF(start))/time

最后对于任何 x=step,

值为 F(a+b*step) 即 什么都没有

F(inverseF(start)+ (inverseF(end)-inverseF(start))/time * step)

就是答案。

例如如果

F(x) 是线性的,即)f(x)=x

值 = start+(end-start)/time*step

如果F(x)是x*x,那么

值 = ( sqrt(start) + (sqrt(end)-sqrt(start))/time * step) * ( sqrt(start) + (sqrt(end)-sqrt(start))/time * step)

如果 F(x) 是 exp(x) 那么

值 = Exp (log(start) + (log(end)-log(start))/time*step)

如果 F(x) 是 log(x) 那么

值 = Log((exp(start) + (exp(end)-exp(start))/time*step)

等等..

下面解释另一种不使用反函数的方法。

对于给定的步骤 x,让函数为 a+b*F(x), 让起始值为start, 让结束值为 end 设开始时间为0,结束时间为时间

然后 a+ b * F(0) = start 和 a + b * F(time) = end,在求解 a & b 时,

你会得到

值 = start + (end-start) / (F(time)-F(0) ) * (F(x)-F(0) )

对于第 x 步,

value = start + (end-start) / (F(time)-F(0) ) * (F(step)-F(0) )

我希望以上任何一项都能解决您的问题..

【讨论】:

【参考方案8】:

我将在另一个问题上重复使用 my answer。为该答案给出的功能不会花太多时间做低负载,而是快速进入中等负载,然后缓慢增加负载以达到最大值。如果您在可能的负载中需要更多值,或者在低负载中需要更多值 - 只需传递适当的分布函数即可。

鉴于您的输入参数,我会这样称呼它:

Spread(startingValue, endingValue, time/step, x => 1-(1-x)*(1-x))

示例算法函数:

FocusOnHighLoad   = x => 1-(1-x)*(1-x)
FocusOnLowLoad    = x => x * x
FocusOnMediumLoad = x => (1 + Math.Pow(x * 2 - 1, 3)) / 2

样本输出:

foreach (double load in Spread(50, 1000, 9, FocusOnHighLoad))
    Console.WriteLine("Working with 0 load", load);

Working with 50 load
Working with 272.65625 load
Working with 465.625 load
Working with 628.90625 load
Working with 762.5 load
Working with 866.40625 load
Working with 940.625 load
Working with 985.15625 load
Working with 1000 load

【讨论】:

以上是关于使用数学算法随时间增加价值的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 1114E(数学+随机算法)

备战数学建模45-模拟退火算法SA(攻坚站9)

备战数学建模45-模拟退火算法SA(攻坚站9)

数学建模 分支限界算法求解整数规划原理以及编程实现

时间复杂度[转]

算法的时间复杂度和空间复杂度