0

这可能不是正确的地方,所以如果不是,请提前道歉。

我的情况 - 我需要想出一个简单的公式/方法给它一个小时,例如 13、15、01 等,并根据该数字,该方法将返回该特定时间的“大约”温度。

这是非常近似的,它不会使用天气数据或类似的东西,它只需要一天中的一个小时并返回一个介于 -6 摄氏度 > 35 摄氏度之间的值。(非常​​极端的天气,但你明白了.)

这是我想知道如何做的例子:

时间vsTemp

正如一个注释,我可以使用一个包含 24 个项目的丑陋数组,每个项目都引用该小时的温度,但这需要基于浮点数 - 例如 19.76 应该返回 9.25 度......

另一个注意事项:我不想要一个完整的解决方案——我是一个对各种语言充满信心的程序员,但数学真的让我很难过。我已经使用 TimeToPeak(高峰时间是下午 1 点或附近)在纸上尝试了各种方法,但无济于事。在这一点上,任何帮助将不胜感激。

4

5 回答 5

3

EDIT

Following your comment, here is a function that provides a sinusoidal distribution with various useful optional parameters.

private static double SinDistribution(
    double value,
    double lowToHighMeanPoint = 0.0,
    double length = 10.0,
    double low = -1.0,
    double high = 1.0)
{
    var amplitude = (high - low) / 2;
    var mean = low + amplitude;
    return mean + (amplitude * Math.Sin(
        (((value - lowToHighMeanPoint) % length) / length) * 2 * Math.PI));
}

You could use it like this, to get the results you desired.

for (double i = 0.0; i < 24.0; i++)
{
    Console.WriteLine("{0}: {1}", i, SinDistribution(i, 6.5, 24.0, -6.0, 35.0));
}

This obviously discounts environmental factors and assumes the day is an equinox but I think it answers the question.


So,

double EstimatedTemperature(double hour, double[] distribution)
{
    var low = Math.Floor(hour);
    var lowIndex = (int)low;
    var highIndex = (int)Math.Ceiling(hour);

    if (highIndex > distribution.Count - 1)
    {
       highIndex = 0;
    }

    if (lowIndex < 0)
    {
        lowIndex = distribution.Count - 1;
    }  

    var lowValue = distribution.ElementAt(lowIndex);
    var highValue = distribution.ElementAt(highIndex);

    return lowValue + ((hour - low) * (highValue - lowValue));
}

assuming a rather simplistic linear transition between each point in the distibution. You'll get erroneous results if the hour is mapped to elements that are not present in the distribution.

于 2013-06-24T11:19:24.807 回答
2

对于任意数据点,我会使用已提供的其他线性插值解决方案之一。

然而,这组特殊的数据是由三角波产生的:

temp = 45*Math.Abs(2*((t-1)/24-Math.Floor((t-1)/24+.5)))-10;
于 2013-06-24T11:47:53.197 回答
1

表中的数据从第 13 小时的峰值和第 1 小时的最小值呈线性上下变化。如果这是您想要的模型类型,那么这很容易放入公式解决方案中。您只需根据小时值在两个极端温度之间执行线性插值。您将有两个数据点:

(xmin, ymin) 作为 (hour-min, temp-min)

(xmax, ymax) 作为 (hour-max, temp-max)

您将有两个形式的方程:

在此处输入图像描述

这两个方程将使用 (x0, y0) 和 (x1, y1) 值作为上述两个数据点,但将它们应用相反的分配(即峰值将是 (x0, y0) 在一个和 (x1, y1) 在其他等式。

然后,您将根据小时值选择要使用的方程,将 X 值插入为小时并计算为 Y 值作为温度值。

您将需要偏移方程式中使用的 X 值,以便您处理 0 小时与最低温度峰值发生位置之间的偏移。

于 2013-06-24T11:39:11.383 回答
1

这是一个示例,说明如何在函数中使用一组简单的值来执行此操作,如果您愿意,可以将它们添加为参数;

    public double GetTemp(double hour)
    {
        int min = 1;
        int max = min + 12;

        double lowest = -10;
        double highest = 35;

        double change = 3.75;

        return (hour > max) ? ((max - hour) * change) + highest : (hour < min) ? ((min - hour)*change) + lowest : ((hour - max) * change) + highest;
    }

我根据您的示例对此进行了测试,它适用于 19.75 = 9.6875。

没有检查输入的值是否在 0-24 之间,但您可能可以自己管理:)

于 2013-06-24T11:47:42.653 回答
0
  1. 您可以使用简单的 2 点线性近似。尝试这样的事情:
    function double hourTemp(double hour)
    {
       idx1 = round(hour); 
       idx2 = idx1 + 1;
       return (data[idx2] - data[idx1]) * (hour - idx1) + data[idx1];
    }
  1. 或者使用 3,5 或更多点通过普通最小二乘法获得多项式系数。
  2. 您的样本数据类似于 sin 函数,因此您可以对 sin 函数进行近似。
于 2013-06-24T11:22:05.880 回答