一个非线性级数的C#聚合函数
本文关键字:函数 一个 非线性 | 更新日期: 2023-09-27 18:00:06
我得到了两个数组,一个表示价格,另一个表示多个单位:
例如
decimal[] price = new decimal[] {1.65, 1.6, 1.55, 1.4, 1.3};
long[] quantity = new long[] {5000, 10000, 12000, 20000, 50000};
因此,前5000台每台售价1.65美元,下一台售价10000美元每台售价1.6美元,以此类推…
当你知道你想要订购的单位数量时,用聚合函数很容易得到平均价格。例如,7000单位的平均价格=(5000/7000*1.65)+(2000/7000*1.6),然而,当总单位数量是未知变量时,我很难想出一个算法,我们得到了目标平均价格。
例如,我必须订购多少台,这样平均单价=1.57
如果你从几何角度考虑,可以考虑一张图表,显示总价格(纵轴)是购买物品总数(横坐标)的函数。情节从(0, 0)
开始(零购买零成本)。首先得到一条斜率为1.65
、水平宽度为5000
的直线段。然后,从其终点来了斜率为1.6
和宽度为10000
的新的段。总的地块是连续的、分段的直线,但在单价变化的地方有弯曲。
然后,为了解决您的问题,找到与方程y == 1.57 * x
的线的交点,即从(0, 0)
开始并具有斜率1.57
的线。对于每个分段(您知道其两个端点),检查该分段是否满足y == 1.57 * x
,如果满足,则有您的解决方案。
如果price
数组中的数字在减少,则最多可以有一个解决方案(假设1.57
严格小于第一个价格price[0]
),该图表示凹函数。
编辑:我试图用C#对这个几何体进行编码。我没有加上price
都是正的和递减的,以及quantity
都是正。你必须检查一下。这是我的代码:
decimal[] price = { 1.65m, 1.6m, 1.55m, 1.4m, 1.3m, };
long[] quantity = { 5000, 10000, 12000, 20000, 50000, };
decimal desiredAverage = 1.57m;
int length = price.Length;
if (length != quantity.Length)
throw new InvalidOperationException();
var abscissaValues = new long[length + 1];
var ordinateValues = new decimal[length + 1];
for (int i = 1; i <= length; ++i)
{
for (int j = 0; j < i; ++j)
{
abscissaValues[i] += quantity[j];
ordinateValues[i] += price[j] * quantity[j];
}
} // calculation of plot complete
int segmentNumber = Enumerable.Range(1, length).FirstOrDefault(i => ordinateValues[i] / abscissaValues[i] <= desiredAverage);
if (segmentNumber > 1)
{
decimal x = (ordinateValues[segmentNumber - 1] * abscissaValues[segmentNumber] - abscissaValues[segmentNumber - 1] * ordinateValues[segmentNumber])
/ (desiredAverage * (abscissaValues[segmentNumber] - abscissaValues[segmentNumber - 1]) - (ordinateValues[segmentNumber] - ordinateValues[segmentNumber - 1]));
Console.WriteLine("Found solution x == " + x);
}
else
{
Console.WriteLine("No solution");
}
我不知道是否有人能把它写得更漂亮,但它似乎奏效了。输出为:
找到的溶液x==29705.882352941176470588235294
我相信这是因为没有一个答案,没有一个价格组合,这将导致的一个平均值,没有闭合形式的方程。我们可能看到的是背包问题的一个变体。http://en.wikipedia.org/wiki/Knapsack_problem其具有值的最小化而不是最大化。
编辑:正如下面正确指出的,这不是背包问题的变体。有一个封闭形式的解决方案:
如果T=购买的总单位,
1.57=1.55*(12000/T)+1.6*(T-12000)/T)。求解T.
起始价格块(此处为1.55)是略低于问题中给出的单位平均价格(此处为1.507)的块。