0

我有两个数组,一个代表价格,另一个代表多个单位:

例如

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

4

2 回答 2

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

于 2013-02-19T20:09:30.453 回答
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)的块。

于 2013-02-19T19:22:56.410 回答