主要内容

在基于问题的框架中创建多期库存模型

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

肥料和配料

颗粒肥料含有氮(N)、磷(P)和钾(K)营养物质。你可以混合以下原料,以获得含有必需营养物质的肥料混合物。

负载肥料混合物= blendDemand.Properties.VariableNames生产化肥的百分比
混合=1 x2单元格{'平衡'}{' HighN '}
营养素= rawNutrients.Properties.RowNames
营养=3 x1细胞{' n '} {' p '} {' k '}
rawes = rawNutrients.Properties.VariableNames%原材料
画=1 x6单元格{'MAP'} {'Potash'} {'AN'} {'AS'} {'TSP'} {'Sand'}

两种混合肥料具有相同的营养需求(按重量计算,10% N, 10% P和10% K),除了“高N”混合肥料有额外的10% N,总共有20% N。

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

原料有以下名称和按重量计算的营养成分百分比。

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

原材料沙子没有营养成分。如果有必要,沙子可以稀释其他成分,以获得所需的营养物质的重量百分比。

将每个数量的数字存储在变量中。

n混合物=长度(混合物);nRaws =长度(raws);nNutrients =长度(营养素);

预测需求和收入

假设您预先知道问题中不同时间段对两种混合肥料的重量(吨)需求。

disp (blendDemand)
平衡高地________ _____ 1月750 300 2月800 310 3月900 600 4月850 400 5月700 350 6月700 300 7月700 200 8月600 200 9月600 200 10月550 200 11月550 200 12月550 200

你知道你每吨出售混合肥料的价格。每吨的价格不受时间的影响。

disp (blendPrice)
平衡高地________ _____ 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月11月310 600 300 125 240 80 310 600 300 125 240 80 600 300 125 240 80 340年12月

存储成本

混合肥料的储存费用按吨和时段计算。

disp (inventoryCost)
10

容量约束

你不能存储超过inventoryCapacity在任何时期总化肥混合吨。

disp (inventoryCapacity)
1000

你总共可以生产不超过productionCapacity在任何时期都是吨。

disp (productionCapacity)
1200

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

您以一定数量或库存的可用混合肥料开始计划。你对期末存货有一定的目标。在每个时间段,混合肥料的数量是前一个时间段结束时的数量,加上产量,减去销售额。换句话说,对于大于1的倍数:

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

这个等式意味着存货在期末被清点。问题中的时间段如下。

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

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

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

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

假设未满足的需求丢失了。换句话说,如果您不能在一段时间内完成所有订单,则超出的订单不会结转到下一段时间。

优化问题公式

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

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

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

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

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

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

根据问题变量计算目标函数,计算收益和成本。收益是你出售每种混合肥料的数量乘以价格,在所有时间段和混合物中添加。

收益= sum(blendPrice{1,:}.*sum(出售(月份,混合),1));

配料成本是每次所用每种配料的成本,加在所有时间段内。因为每次使用的量被分开到每个混合物中使用的量,也添加到混合物中。

blendsUsed = sum(使用(月份,raw,混合物),3);配料成本= sum(sum(rawCost{months,raws}.*blendsUsed));

存储成本是在每个时间段内存储库存的成本,随着时间的推移而增加并混合。

存储成本=库存成本*sum(库存(:));

现在把目标函数放到客观的用点表示法来表示问题的性质。

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

问题的约束

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

materialBalance = optimconstr(月份,混合);timeAbove1 = months(2:结束);previousTime = months(1:end-1);materialBalance(timeAbove1,:) = inventory(timeAbove1,:) == inventory(previousTime,:) +...make(timeAbove1,:) - sell(timeAbove1,:);materialBalance(1,:) =库存(1,:)== blendInventory{“初始”:} +...Make (1,:) - sell(1,:);

同时也要说明最终库存是固定的。

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

每个时刻的总库存是有界的。

boundedInv = sum(库存,2)<=库存容量;

你可以在每个时间段生产有限的数量。

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

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

rawMaterialUse =挤压(sum(使用(月份,raw,混合物),2))== make(月份,混合物);

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

blendNutrientsQuality = optimconstr(月份,营养素,混合物);m = 1:nMonthsb = 1:n次混合n = 1:nNutrients blendNutrientsQuality(m,n,b) = rawNutrients{n,raws}*use(m,raws,b)' == 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;

解决问题

问题的公式是完整的。解决问题。

[sol,fval,exitflag,output] = solve(inventoryProblem)
用linprog解决问题。找到最优解。
索尔=带字段的结构:库存:[12x2 double]制造:[12x2 double]销售:[12x2 double]使用:[12x6x2 double]
Fval = 2.2474e+06
exitflag = OptimalSolution
输出=带字段的结构:消息:'找到最佳解决方案。firstorderopt: 6.5235e-12 solver: 'linprog'

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

如果退出> 0 fprintf(“利润:% g \ n”, fval);= array2table(sol.make,“RowNames”个月,“VariableNames”, strcat (“使”、混合));selt = array2table(sol.sell,“RowNames”个月,“VariableNames”, strcat (“卖出”、混合));storeT = array2table(sol.inventory,“RowNames”个月,“VariableNames”, strcat (“存储”、混合));productionPlanT = [makeT selt storeT]图subplot(3,1,1) bar(sol.make)图例(“平衡”“HighN”“位置”“eastoutside”)标题(“数量”) subplot(3,1,2) bar(sol.sell)图例(“平衡”“HighN”“位置”“eastoutside”)标题(的销售数量) subplot(3,1,3) bar(sol.inventory)图例(“平衡”“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年8月200年9月600 200 600 200 600 200 0 0 0 0 550年10月200年11月550 200 550 200 550 200 0 0 0 0 400 550 200 200 200 750年12月

图中包含3个轴对象。标题为Amount Made的Axes对象1包含2个类型为bar的对象。这些对象代表Balanced, HighN。标题为Amount Sold的坐标轴对象2包含2个类型为bar的对象。这些对象代表Balanced, HighN。标题为Amount Stored的Axes对象3包含2个类型为bar的对象。这些对象代表Balanced, HighN。

相关的话题