主要内容

在基于问题的框架下建立多周期库存模型

这个例子展示了如何在基于问题的框架中创建一个多周期库存模型。问题是在一段时间内安排混合肥料的生产,使用各种原料,这些原料的成本以一种可预测的方式取决于时间。假设你事先知道肥料的需求。目标是在满足需求的同时实现利润最大化,而需求的成本是购买原材料和长期储存肥料的成本。你可以通过期货或其他合同提前确定成本。

化肥和成分

粒状肥料含有氮(N)、磷(P)和钾(K)等营养物质。您可以将以下原料混合,以获得与所需营养物质混合的肥料。

负载肥料混合= blendDemand.Properties.VariableNames化肥产量%
混合=1 x2单元格{'平衡'}{' HighN '}
营养= rawNutrients.Properties.RowNames
营养=3 x1细胞' P ' {' N '}{}{“K”}
画= rawNutrients.Properties.VariableNames%的原材料
画=1 x6单元格{'MAP'} {'Potash'} {'AN'} {'AS'} {'TSP'} {'Sand'}

两种肥料混合物的营养需求相同(10% N, 10% P, 10% K),除了“高N”混合物增加了10% N,总共增加了20% N。

disp (blendNutrients)表格以百分比表示
平衡HighN ________ _____ N 10 20 P 10 10 K 10 10

原料的名称和营养成分的重量百分比如下。

disp (rawNutrients)表格以百分比表示
MAP钾肥AN AS TSP Sand ___ ______ ____ ___ ____ N 11 0 35 21 0 0 P 48 0 0 46 0 K 0 60 0 0 0 0

原料沙子不含营养成分。如果有必要,沙子会稀释其他成分,以获得所需的营养成分的重量百分比。

将这些数量中的每一个存储在变量中。

nBlends =长度(混合);nRaws =长度(画);nNutrients =长度(营养);

预测需求及收入

假设您提前知道了问题发生期间两种化肥混合物的重量(吨)需求。

disp (blendDemand)
平衡HighN ________ _____一月750 300二月800 310三月900 600四月850 400五月700 350六月700 300七月700 200八月600 200九月600 200十月550 200十一月550 200十二月550 200

你知道每吨化肥的售价。每吨的价格不取决于时间。

disp (blendPrice)
平衡HighN ________ _____ 400 550

原材料价格

假设你提前知道原料的吨数价格。根据下表,每吨的价格取决于时间。

disp (rawCost)
地图钾肥TSP沙子  ___ ______ ___ ___ ___ ____ 630年1月360年2月350 610 300 135 250 80 300 140 275 80 350 630 300 135 275 80 3月350年4月320年5月610 300 125 250 80 600 300 125 250 80 320 600 300 125 250 80 6月7月8月320 600 300 125 250 80 320 600 300 125 240 80 320 600 300 125 240 80 9月10月310 600 300 125 24080 11月310 600 300 125 240 80 12月340 600 300 125 240 80

存储成本

混合肥料的储存成本适用于每吨和每一时期。

disp (inventoryCost)
10

容量约束

你只能储存inventoryCapacity在任何时期的总肥料混合吨数。

disp (inventoryCapacity)
1000

你能产生的总数不超过productionCapacity吨在任何时期。

disp (productionCapacity)
1200

生产、销售和库存之间的联系

在计划开始时,你要准备一定量的混合肥料。在最后阶段,你有一个特定的库存目标。在每个时间段,肥料的混合量是前一个时间段结束时的数量,加上生产的数量,减去销售的数量。换句话说,对于大于1的次数:

库存(时间,产品)=库存(时间-1,产品)+生产(时间,产品)-销售(时间,产品)

这个等式意味着存货是在这个时期的末期计算的。问题中的时间段如下。

个月= blendDemand.Properties.RowNames;nMonths =长度(个月);

初始库存对时间1的库存影响如下。

库存(1,产品)=初始库存(产品)+生产(1,产品)-销售(1,产品)

初始库存在数据中blendInventory{“初始”:}.最后的库存在数据中blendInventory{“最终”:}

假设未满足的需求消失了。换句话说,如果您不能在一个时间段内完成所有订单,多余的订单将不会转入下一个时间段。

优化问题制定

这个问题的目标函数是利润,你想要最大化它。因此,在基于问题的框架中创建一个最大化问题。

inventoryProblem = optimproblem (“ObjectiveSense”“最大化”);

这个问题的变量是你每个月生产和销售的混合肥料的数量,以及你用来混合肥料的原料。上限值出售的需求,blendDemand,每一段时间和每一种肥料混合。

使= optimvar (“使”,几个月,混合,下界的, 0);销售= optimvar (“卖出”,几个月,混合,下界的0,“UpperBound”blendDemand{月,混合});使用= optimvar (“使用”,月,画,混合,下界的, 0);

另外,每次创建一个表示库存的变量。

库存= optimvar (“库存”,几个月,混合,下界的0,“UpperBound”, inventoryCapacity);

用问题变量来计算目标函数,计算收入和成本。收入是每一种肥料混合物的销售量乘以价格,加上所有时间段和混合物。

收入=总和(blendPrice{1,}。*总和(销售(月,混合),1));

配料成本是指每次使用的每一种配料的成本,加上所有时间段。因为每次使用的量被分割成每次混合使用的量,也加在混合的量上。

blendsUsed =总和(使用(月,画,混合),3);ingredientCost =总和(总和(rawCost{月,画}。* blendsUsed));

存储成本是在每个时间段内存储存货的成本,随时间增加并混合。

storageCost = inventoryCost *总和(库存(:));

现在把目标函数放入客观的用点符号表示问题的性质。

inventoryProblem。客观的= revenue - ingredientCost - storageCost;

问题的约束

这个问题有几个限制条件。首先,将库存方程表示为问题变量的约束集。

materialBalance = optimconstr(月、混合);timeAbove1 =月(2:结束);previousTime =月(1:end-1);materialBalance(timeAbove1,:) = inventory(timeAbove1,:) == inventory(previousTime,:) +...制造(timeAbove1:) -销售(timeAbove1:);materialBalance(1,:) = inventory(1,:) == blendInventory{“初始”:} +...制造(1:)—销售(1:);

同时表示最终库存是固定的约束条件。

finalC = inventory(end,:) == blendInventory{“最后一次”,:};

每次的总库存是有界的。

boundedInv = sum(inventory,2) <= inventoryCapacity;

您可以在每个时间段内生产一定数量的产品。

processLimit = sum(make,2) <= productionCapacity;

你每个月生产的每种混合物的数量就是你使用的原材料的数量。的挤压函数将和转换为anmonths-by-1-by -nblends数组,nmonths——- - - - - -nblends数组中。

rawMaterialUse = squeeze(sum(use(months,raws,共混),2))== make(months,共混);

每种混合物中的营养成分都必须具有必要的价值。在下面的内部语句中,乘法运算rawNutrients {n,画}*使用(m,画,b) '每次添加的营养价值超过使用的原材料。

blendNutrientsQuality = optimconstr(个月,营养,混合);m = 1: nMonthsb = 1: nBlendsn = 1:nNutrients blendNutrientsQuality(m,n,b) = rawNutrients{n,raws}*use(m,raws)' == blendNutrients{n,b}*make(m,b);结束结束结束

将约束条件放入问题中。

inventoryProblem.Constraints.materialBalance = materialBalance;inventoryProblem.Constraints.finalC = finalC;inventoryProblem.Constraints.boundedInv = boundedInv;inventoryProblem.Constraints.processLimit = processLimit;inventoryProblem.Constraints.rawMaterialUse = rawMaterialUse;inventoryProblem.Constraints.blendNutrientsQuality = blendNutrientsQuality;

解决问题

问题的表述已经完成了。解决这个问题。

[溶胶,fval exitflag、输出]=解决(inventoryProblem)
使用linprog解决问题。找到最优解。
索尔=结构体字段:库存:[12x2 double] make: [12x2 double] sell: [12x2 double] use: [12x6x2 double]
fval = 2.2474 e + 06
exitflag = OptimalSolution
输出=结构体字段:迭代:154构造:5.4570e-12信息:“找到了最佳解决方案。第一个算法:6.5235e-12 solver: 'linprog'

以表格和图形形式显示结果。

如果Exitflag > 0 fprintf(“利润:% g \ n”, fval);市场= array2table (sol.make,“RowNames”个月,“VariableNames”, strcat (“使”、混合));sellT = array2table (sol.sell,“RowNames”个月,“VariableNames”, strcat (“卖出”、混合));storeT = array2table (sol.inventory,“RowNames”个月,“VariableNames”, strcat (“存储”、混合));productionPlanT = [makeT sellT storeT] figure subplot(3,1,1) bar(sol.make) legend(“平衡”“HighN”“位置”“eastoutside”)标题(“数量”) subplot(3,1,2) bar(sol.sell) legend(“平衡”“HighN”“位置”“eastoutside”)标题(的销售数量) subplot(3,1,3) bar(sol.inventory) legend(“平衡”“HighN”“位置”“eastoutside”)标题(量存储的)包含(“时间”结束
利润:2.24739 e + 06
productionPlanT =12×6表makeBalanced makeHighN sellBalanced sellHighN storeBalanced storeHighN  ____________ _________ ____________ _________ _____________ __________ 1100年1月600年2月100 750 300 550 0 310 800 310 350 0 600年3月550 650 900 0 850年4月350年5月700 350 700 350 850 400 0 0 0 0 700年6月200年7月700 200 700 300 700 300 0 0 0 0 600 200 600 8月200 00 9月600 200 600 200 00 10月550 200 550 200 00 11月550 200 550 200 00 12月750 400 550 200 200 200 200 200

图中包含3个轴对象。标题为“制造数量”的轴对象1包含2个类型为bar的对象。这些对象代表平衡,HighN。标题为“售出数量”的轴对象2包含2个类型为bar的对象。这些对象代表平衡,HighN。标题为Amount Stored的轴对象3包含2个bar类型的对象。这些对象代表平衡,HighN。

相关的话题