2

我目前正在实施一个软件,可以随着时间的推移测量某些值。用户可以选择在 28 天的时间内测量该值 100 次。(只是举个例子)

线性分布不是问题,但我目前正在尝试在时间跨度上获得点的对数分布。

直接的实现是迭代这些点,因此我需要一个指数函数。(我已经走到这一步了!)

我当前的算法(C#)如下:

long tRelativeLocation = 0;
double tValue;
double tBase = PhaseTimeSpan.Ticks;
int tLastPointMinute = 0;
TimeSpan tSpan;
for (int i = 0; i < NumberOfPoints; i++)
{
     tValue = Math.Log(i + 1, NumberOfPoints);

     tValue = Math.Pow(tBase, tValue);
     tRelativeLocation = (long)tValue;
     tSpan = new TimeSpan(tRelativeLocation);
     tCurrentPoint = new DefaultMeasuringPointTemplate(tRelativeLocation);
     tPoints.Add(tCurrentPoint);
}

这给了我 28 天和 100 分的相当“好”的结果。
前 11 个点都在 0 秒,
第 12 点在 1 秒,
第 20 点在 50 秒,
第 50 点在 390 分钟,
第 95 点在 28605 分钟
第 99 点在 37697 分钟(这使得 43 小时到最后一点)

我的问题是:有没有人知道如何让前 20-30 分彼此分开更远,也许让最后 20-30 分更接近一点?

我知道我最终将不得不添加一些算法,将第一点分开至少一分钟左右,因为我无法将这种行为纳入严格的数学算法中。

像这样的东西:

if (((int)tSpan.TotalMinutes) <= tLastPointMinute)
{
      tSpan = new TimeSpan((tLastPointMinute +1) * 600000000L);
      tRelativeLocation = tSpan.Ticks;
      tLastPointMinute = (int)tSpan.TotalMinutes;
}

但是,我希望总体上获得更好的分布。

任何来自你数学裂缝的很酷的想法都将不胜感激!

4

3 回答 3

1

您选择的分布曲线取决于您要测量的内容。

直线、正弦波、多项式或指数曲线可以单独地成为给定测量集的最佳分布曲线。

确定分布曲线后,您可以使用曲线的数学公式计算任何给定时间值(x 值)的 y 值来计算缺失数据点。

例如,对于一条直线,您只需要一个数据点和直线的斜率。假设在时间 0 测量值为 10,并且测量值每分钟增加 2。公式为 y = 2 * x + 10。如果我们想在 x = 5(分钟)时计算测量值,则公式为我们提供 20 的测量值。

对于对数曲线,您将使用对数公式。为简单起见,假设实际测量结果为我们提供了 y = 2 ** x + 12 的公式;您插入要计算的时间值(x 值),然后计算测量值(y 值)。

意识到您通过计算数据点而不是测量来引入计算错误。您应该以某种方式标记计算的数据点,以帮助阅读图表的人将它们与实际测量值区分开来。

于 2010-07-29T12:57:41.977 回答
1

我不确定您要做什么,您的代码似乎与您的示例不匹配(可能是我搞砸了算术)。如果您希望样本的最小间隔为 1 秒,并且每个点的位置是最后一个点的 x 倍(第一个点除外),那么您希望找到 x 使得 x^(n - 1) = span。这只是 x = exp(log(span) / (n - 1))。那么你的分数将在 x^ifor(i = 0; i < n; i++)

于 2010-07-29T14:37:11.240 回答
1

从实际的角度来看,日志功能已经将您的时间点压缩在原点附近。幂函数进一步挤压它们。简单的乘法呢?

 tValue = Math.Log(i + 1, NumberOfPoints);
 tValue = tBase * tValue;

另一种使曲线变平的方法是从远离原点开始。

for (int i = 0; i < NumberOfPoints; i++)
{
  tValue = Math.Log(i + 10, NumberOfPoints + 9);

tvalue 的范围仍然是 0 到 1。

在开始时至少有 1 秒的空间怎么样?

double nextTick = 0;
for (int i = 0; i < NumberOfPoints; i++)
{
  tValue = Math.Log(i + 1, NumberOfPoints);

  tValue = Math.Pow(tBase, tValue);

  if (tValue < nextTick) tValue = nextTick;
  nextTick++;
于 2010-07-30T17:08:54.003 回答