假设总持续时间是n
,而不是 20。当强度i
变化时,您的函数会做两件事:
- 首先,
k(i)
,周期数发生变化。它从 开始k(0) = 1
,在 达到峰值k(0.5) = n/2
,然后下降到k(1) = 1
。
- 其次,
r(i)
每对中的开/关时间比率发生变化。如果我们有一个循环[a, b]
,a
即有时间,b
有时间,那么r(i)*a = b
。以您的示例为例,我们有r(0) = 0
, r(0.5) = 1
,然后是一个渐近线r(1) = infinity
有很多函数可以匹配k(i)
和r(i)
,但让我们坚持使用简单的函数:
k(i) = (int) (n/2 - (n-2)*|i - 0.5|) r(i) = 1 / (1.000001 - i) - 1
其中|x|
表示 的绝对值x
。我还替换1
了1.000001
inr
的分母,这样我们就不必处理被零除的错误。
现在如果循环需要总和为n
,那么任何一个循环的长度[a, b]
都是n/k(i)
。既然我们也有它r(i)*a = b
,那么它遵循
a = n/(k*(1+r)) b = r*a
为了形成强度数组i
,我们只需要重复[a, b]
k
几次。以下是 的输出示例n = 20
:
Intensity: 0.00, Timings: 20.0, 0.0
Intensity: 0.05, Timings: 9.5, 0.5, 9.5, 0.5
Intensity: 0.10, Timings: 6.0, 0.7, 6.0, 0.7, 6.0, 0.7
Intensity: 0.15, Timings: 4.3, 0.7, 4.3, 0.7, 4.3, 0.7, 4.3, 0.7
Intensity: 0.20, Timings: 3.2, 0.8, 3.2, 0.8, 3.2, 0.8, 3.2, 0.8, 3.2, 0.8
Intensity: 0.25, Timings: 2.5, 0.8, 2.5, 0.8, 2.5, 0.8, 2.5, 0.8, 2.5, 0.8, 2.5, 0.8
Intensity: 0.30, Timings: 2.0, 0.9, 2.0, 0.9, 2.0, 0.9, 2.0, 0.9, 2.0, 0.9, 2.0, 0.9, 2.0, 0.9
Intensity: 0.35, Timings: 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9
Intensity: 0.40, Timings: 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9
Intensity: 0.45, Timings: 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9
Intensity: 0.50, Timings: 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0
Intensity: 0.55, Timings: 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1, 0.9, 1.1
Intensity: 0.60, Timings: 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3, 0.9, 1.3
Intensity: 0.65, Timings: 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6, 0.9, 1.6
Intensity: 0.70, Timings: 0.9, 2.0, 0.9, 2.0, 0.9, 2.0, 0.9, 2.0, 0.9, 2.0, 0.9, 2.0, 0.9, 2.0
Intensity: 0.75, Timings: 0.8, 2.5, 0.8, 2.5, 0.8, 2.5, 0.8, 2.5, 0.8, 2.5, 0.8, 2.5
Intensity: 0.80, Timings: 0.8, 3.2, 0.8, 3.2, 0.8, 3.2, 0.8, 3.2, 0.8, 3.2
Intensity: 0.85, Timings: 0.8, 4.2, 0.8, 4.2, 0.8, 4.2, 0.8, 4.2
Intensity: 0.90, Timings: 0.7, 6.0, 0.7, 6.0, 0.7, 6.0
Intensity: 0.95, Timings: 0.5, 9.5, 0.5, 9.5
Intensity: 1.00, Timings: 0.0, 20.0
这是伪劣代码:
public void Test()
{
foreach (var intensity in Enumerable.Range(0, 20 + 1).Select(i => i/20f))
{
var cycle = new List<float> {a(intensity), b(intensity)};
var timings = Enumerable.Repeat(cycle, k(intensity)).SelectMany(timing => timing).ToArray();
SDebug.WriteLine(
String.Format("Intensity: {0,2:N2}, Timings: ", intensity) +
String.Join(", ", timings.Select(timing => String.Format("{0,2:N1}", timing))));
}
}
private static float r(float i)
{
return 1f/(1.000001f - i) - 1f;
}
private static int k(float i)
{
return Mathf.CeilToInt(10 - 18*Mathf.Abs(i - 0.5f));
}
private static float a(float i)
{
return 20/(k(i)*(1 + r(i)));
}
private static float b(float i)
{
return r(i)*a(i);
}
从这里做的最好的事情就是弄乱函数r(i)
。但是,如果可以,请先将第一个和最后一个时间放宽为[n, 1]
and ,这样[1, n]
您就不必为渐近线烦恼了。