C#聚合函数用于非线性系列

时间:2013-02-19 19:14:40

标签: c# math algebra calculus

我给了两个数组,一个代表价格,另一个代表一些单位:

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

2 个答案:

答案 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)。