C# 如何使用定义的采样数通过3个点/数字进行插值?(c)中
例如,我们有1,5,和10,我们想用12个点在它们之间插值,我们应该得到:C# 如何使用定义的采样数通过3个点/数字进行插值?(c)中,c#,.net,interpolation,C#,.net,Interpolation,例如,我们有1,5,和10,我们想用12个点在它们之间插值,我们应该得到: 1.0000 1.7273 2.4545 3.1818 3.9091 4.6364 5.4545 6.3636 7.2727 8.1818 9.0909 10.0000 5.0000 5.9091 6.8182 7.7273 8.6364 9.5455 9.4545 8.3636 7.2727 6.1818 5.0909 4.000
1.0000
1.7273
2.4545
3.1818
3.9091
4.6364
5.4545
6.3636
7.2727
8.1818
9.0909
10.0000
5.0000
5.9091
6.8182
7.7273
8.6364
9.5455
9.4545
8.3636
7.2727
6.1818
5.0909
4.0000
假设我们有5分、10分和4分,再加上12分,我们应该得到:
1.0000
1.7273
2.4545
3.1818
3.9091
4.6364
5.4545
6.3636
7.2727
8.1818
9.0909
10.0000
5.0000
5.9091
6.8182
7.7273
8.6364
9.5455
9.4545
8.3636
7.2727
6.1818
5.0909
4.0000
问题是给定端点和交点的两条具有不同斜率的直线的插值 插值的定义如下:在数值分析的数学领域,插值是在一组离散的已知数据点范围内构造新数据点的方法 我厌倦了人们对解决棘手问题的方法给予负面评价。这不是一个简单的问题,而是一个需要开箱思考的问题。让我们看看以下输入的解决方案:1 12 34 我选择这些数字是因为结果都是整数 步长L较低=从1到12的元素距离=2 步长H更高=从12到34的元素距离=4 所以答案是:1 3 5 7 9 11[12]14 18 22 26 30 34 请注意,第6点11和中心之间的距离是L的一半 请注意,中心点12和第7点之间的距离为H的2/2 最后请注意,第6点和第7点之间的距离为3 我的结果与第一个例子完全相同。 很难看到OP发布的分数输入序列。如果您查看OP first示例并计算前6个点的步距,则得到0.72。最后6点的距离为0.91。然后计算从第6点到中心的距离为0.36/0.72。然后居中至第7点0.45分0.91分的一半。请原谅我把数字四舍五入一点 这是一个序列问题,就像初中时学习算术和几何序列一样。然后作为一个额外的问题,你得到了序列23,28,33,42,51,59,68,77,86,这是纽约第三大道地铁系统的火车站。解决这样的问题,你需要跳出IBM给求职者的测试的框框来思考。这些人可以解决九点问题: 当分数为偶数时,我做了结果,在你的情况下是12。如果点数为奇数,则需要完成代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
const int NUMBER_POINTS = 12;
static void Main(string[] args)
{
List<List<float>> tests = new List<List<float>>() {
new List<float>() { 1,5, 10},
new List<float>() { 5,10, 4}
};
foreach (List<float> test in tests)
{
List<float> output = new List<float>();
float midPoint = test[1];
if(NUMBER_POINTS % 2 == 0)
{
//even number of points
//add lower numbers
float lowerDelta = (test[1] - test[0])/((NUMBER_POINTS / 2) - .5F);
for (int i = 0; i < NUMBER_POINTS / 2; i++)
{
output.Add(test[0] + (i * lowerDelta));
}
float upperDelta = (test[2] - test[1]) / ((NUMBER_POINTS / 2) - .5F); ;
for (int i = 0; i < NUMBER_POINTS / 2; i++)
{
output.Add(test[1] + (i * upperDelta) + (upperDelta / 2F));
}
}
else
{
}
Console.WriteLine("Numbers = {0}", string.Join(" ", output.Select(x => x.ToString())));
}
Console.ReadLine();
}
}
}
这是一个通用的解决方案,其工作原理如下: 执行线性插值 它计算输入数组中的浮点索引 如果小数部分非常接近输入数组中的0或2个数字,则使用此索引选择1 此索引的整数部分是基本输入数组索引 小数部分表示我们应该向下一个数组元素移动多远 这应该适用于您需要的任何大小的输入数组和输出集合
public IEnumerable<double> Interpolate(double[] inputs, int count)
{
double maxCountForIndexCalculation = count - 1;
for (int index = 0; index < count; index++)
{
double floatingIndex = (index / maxCountForIndexCalculation) * (inputs.Length - 1);
int baseIndex = (int)floatingIndex;
double fraction = floatingIndex - baseIndex;
if (Math.Abs(fraction) < 1e-5)
yield return inputs[baseIndex];
else
{
double delta = inputs[baseIndex + 1] - inputs[baseIndex];
yield return inputs[baseIndex] + fraction * delta;
}
}
}
它生成您在问题中显示的两个输出集合,但除此之外,我还没有测试它。执行的错误检查很少,因此您应该添加必要的位。@TheGeneral这似乎只为两点指定了一种方式。您可能会对@TheGeneral感兴趣,它似乎使用了x,y和x2,x2的点。有没有办法只用n个数字就能做到这一点?我可能会误解。@MinimumEntropy,如果你只有数字,而没有点,那么可能的结果是无限的。此外,您的序列不准确包含第二个数字。请更清楚地解释您想要的插值类型,因为现在知道您想要线性插值还是某种样条插值的唯一方法是绘制或仔细分析您发布的数字。问题不是简单的插值。这是复杂的,我不认为这个代码将工作。该解决方案需要两个范围和不同的参数,具体取决于偶数或奇数点数。这可能是正确的,但请提供一个您知道/认为处理不当的测试场景,即输入集合+计数->预期输出。仅仅说这样做不正确是不够的,因为它完美地生成了问题的输出,也不能帮助我修复代码。因此,撇开评论和否决票不谈,我不知道如何改进,因为没有给出明确的方向。请阅读我给出细节的回复。我更新了我的回复,在有人给我负面评价后,在看到你的答案是错误的后,我发表了评论。我在你的答案中没有看到任何东西使我的答案无效。事实上,我会大胆猜测,给定12个数字的示例序列1->12->34不应该产生您已经产生的数字。OP给出的示例不包含10,因为10位于两个输出数字之间,因此我认为序列也不应该产生12。考虑到没有人100%知道这里是什么,只有OP发布的示例序列我仍然相信我的答案是正确的 rms虽然这不是严格意义上的插值,但采样可能是他的序列的正确术语。