我给了两个数组,一个代表价格,另一个代表一些单位:
e.g。
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),但是,我总是难以想出一个算法,当总单位数量是未知变量时,我们会得到目标平均价格。
E.g。我需要订购多少单位才能平均单价= 1.57
答案 0 :(得分:2)
如果您对其进行几何考虑,请考虑一个图表,显示总价格(纵坐标轴)与购买的项目总数(横坐标)的函数关系。该图从(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
答案 1 :(得分:0)
我认为这是因为没有一个答案,没有一个价格组合,这将导致一个平均值,没有紧密形式的等式。我们可能正在看的是背包问题的变体。 http://en.wikipedia.org/wiki/Knapsack_problem最小化价值而不是最大化。
编辑:正如下面正确指出的,这不是背包问题的变体。有一个封闭的形式解决方案:
如果T =购买的总单位,
1.57 = 1.55 *(12000 / T)+ 1.6 *((T-12000)/ T)。解决T.
起始价格区块(此处为1.55)是刚好低于问题中给出的每单位平均价格的区块(此处为1.57)。