Main Content

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

This example shows how to create a multiperiod inventory model in the problem-based framework. The problem is to schedule production of fertilizer blends over a period of time using a variety of ingredients whose costs depend on time in a predictable way. Assume that you know in advance the demand for the fertilizers. The objective is to maximize profits while meeting demand, where the costs are for purchasing raw ingredients and for storing fertilizer over time. You can determine costs in advance by using futures or other contracts.

Fertilizers and Ingredients

Granular fertilizers have nutrients nitrogen (N), phosphorous (P), and potassium (K). You can blend the following raw materials to obtain fertilizer blends with the requisite nutrients.

loadfertilizer混合=blendDemand.Properties.VariableNames% Fertilizers to produce
混合=1x2 cell{'Balanced'} {'HighN'}
营养=rawNutrients.Properties.RowNames
营养=3x1 cell{'n'} {'p'} {'k'}
RAWS =rawNutrients.Properties.VariableNames% Raw materials
RAWS =1x6单元{'MAP'} {'Potash'} {'AN'} {'AS'} {'TSP'} {'Sand'}

这two fertilizer blends have the same nutrient requirements (10% N, 10% P, and 10% K by weight), except the "HighN" blend has an additional 10% N for a total of 20% N.

disp(blendNutrients)百分比为百分比
平衡高________ _____ n 10 20 P 10 10 K 10 10

这raw materials have the following names and nutrient percentages by weight.

disp(rawnutients)百分比为百分比
地图钾肥AS TSP砂___ ______ ____________ ____ N 11 0 35 21 0 0 P 48 0 0 0 0 46 0 K 0 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

这raw materialhas no nutrient content. Sand dilutes other ingredients, if necessary, to obtain the requisite percentages of nutrients by weight.

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

nBlends = length(blends); nRaws = length(raws); nNutrients = length(nutrients);

Forecast Demand and Revenue

Assume that you know in advance the demand in weight (tons) for the two fertilizer blends for the time periods in the problem.

disp(blendDemand)
平衡HIGHN ______________________________________________________________________________EN 75S 3月800 310 310 310 310 310 310 310 4月850 400 350 350 6月700 300 300 700 700 700 2002年8月600日200年8月600月600 9月600月2000年10月550日2000年11月20050年12月20050年12月20050年12月550

You know the prices per ton at which you sell the fertilizer blends. These prices per ton do not depend on time.

disp(blendPrice)
Balanced HighN ________ _____ 400 550

Prices of Raw Materials

Assume that you know in advance the prices in tons for the raw materials. These prices per ton depend on time according to the following table.

disp(awarcost)
MAP Potash AN AS TSP Sand ___ ______ ___ ___ ___ ____ January 350 610 300 135 250 80 February 360 630 300 140 275 80 March 350 630 300 135 275 80 April 350 610 300 125 250 80 May 320 600 300 125 250 80 June 320 600 300 125 250 80 July 320 600 300 125 250 80 August 320 600 300 125 240 80 September 320 600 300 125 240 80 October 310 600 300 125 240 80 November 310 600 300 125 240 80 December 340 600 300 125 240 80

Storage Cost

储存混合肥料的成本适用于每吨和每个时间段。

disp(inventoryCost)
10

容量限制

You can store no more thaninventoryCapacitytons of total fertilizer blends at any time period.

disp(库存容量)
1000

You can produce a total of no more thanproductionCapacity在任何时间段。

disp(生产容量)
1200

Connection Among Production, Sales, and Inventory

您可以从可用的肥料混合物中以一定的数量或清单开始计划。您在最后一个阶段有一个库存的目标。在每个时间段内,肥料混合物的数量是上一个时期结束时的金额,以及所产生的金额,减去了出售的金额。换句话说,有时大于1:

inventory(time,product) = inventory(time-1,product) + production(time,product) - sales(time,product)

This equation implies that the inventory is counted at the end of the time period. The time periods in the problem are as follows.

月= Blenddemand.properties.Rownames;nmonths =长度(月);

这initial inventory affects the inventory at time 1 as follows.

库存(1,product)= initialInventory(Product) +生产(1,产品) - 销售(1,产品)

最初的库存在数据中BlendinVentory {'初始',:}。最终库存在数据中blendInventory{'Final',:}

Assume that unmet demand is lost. In other words, if you cannot fill all the orders in a time period, the excess orders do not carry over into the next time period.

优化问题公式

这objective function for this problem is profit, which you want to maximize. Therefore, create a maximization problem in the problem-based framework.

inventoryProblem = optimproblem(“目标义”,,,,'maximize');

这variables for the problem are the quantities of fertilizer blends that you make and sell each month, and the raw ingredients that you use to make those blends. The upper bound onsell是需求,blendDemand,对于每个时间段和每个肥料混合。

make = optimvar('制作',几个月,blends,“下界”,0);sell = optimvar('卖',几个月,blends,“下界”,,,,0,“上行”,,,,blendDemand{months,blends}); use = optimvar('利用',几个月,raws,blends,“下界”,0);

Additionally, create a variable that represents the inventory at each time.

库存= optimvar('inventory',几个月,blends,“下界”,,,,0,“上行”,,,,inventoryCapacity);

To calculate the objective function in terms of the problem variables, calculate the revenue and costs. The revenue is the amount you sell of each fertilizer blend times the price, added over all time periods and blends.

revenue = sum(blendPrice{1,:}.*sum(sell(months,blends),1));

原料成本是每个ingre成本dient used at each time, added over all time periods. Because the amount used at each time is separated into the amount used for each blend, also add over the blends.

blendsUsed = sum(use(months,raws,blends),3); ingredientCost = sum(sum(rawCost{months,raws}.*blendsUsed));

这storage cost is the cost for storing the inventory over each time period, added over time and blends.

storageCost = inventoryCost*sum(inventory(:));

Now place the objective function into theObjective通过使用点表示法的属性。

inventoryProblem.Objective = revenue - ingredientCost - storageCost;

Problem Constraints

这problem has several constraints. First, express the inventory equation as a set of constraints on the problem variables.

materialBalance = optimconstr(months,blends); timeAbove1 = months(2:end); previousTime = months(1:end-1); materialBalance(timeAbove1,:) = inventory(timeAbove1,:) == inventory(previousTime,:) +...make(timeAbove1,:) - sell(timeAbove1,:); materialBalance(1,:) = inventory(1,:) == blendInventory{'Initial',:} +...制作(1,:)  - 出售(1,:);

Express the constraint that the final inventory is fixed as well.

finalC = inventory(end,:) == blendInventory{'Final',,,,:};

这total inventory at each time is bounded.

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

You can produce a limited amount in each time period.

processlimit = sum(make,2)<=生产能力;

您每个混合物的每个月生产的金额是您使用的原材料量。这function converts the sum from anmonths-by-1-by-nblendsarray to anmonths-by-nblendsarray.

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

这nutrients in each blend must have the requisite values. In the following inner statement, the multiplicationrawNutrients{n,raws}*use(m,raws,b)'在所使用的原材料上,每次添加营养价值。

blendNutrientsQuality = optimconstr(months,nutrients,blends);为了m = 1:nmonths为了b = 1:nBlends为了n = 1:nNutrients blendNutrientsQuality(m,n,b) = rawNutrients{n,raws}*use(m,raws,b)' == blendNutrients{n,b}*make(m,b);endendend

Place the constraints into the problem.

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

Solve Problem

这problem formulation is complete. Solve the problem.

[SOL,FVAL,EXITFLAG,输出] = solve(库存问题)
Solving problem using linprog. Optimal solution found.
sol =struct with fields:inventory: [12x2 double] make: [12x2 double] sell: [12x2 double] use: [12x6x2 double]
fval = 2.2474e+06
exitflag = OptimalSolution
output =struct with fields:迭代:154约束:5.4570E-12消息:“找到最佳解决方案”。算法:'Dual-Simplex'FirstorderOpt:6.5235E-12求解器:'linprog'

Display the results in tabular and graphical form.

ifexitflag> 0 fprintf('Profit: %g\n',,,,fval); makeT = array2table(sol.make,'Rownames',几个月,'variablenames',,,,strcat('制作',混合));sallt = array2table(sol.sell,'Rownames',几个月,'variablenames',,,,strcat('卖',混合));storeT = array2table(sol.inventory,'Rownames',几个月,'variablenames',,,,strcat('store',混合));生产植物= [maket sallt storet]图子图(3,1,1)bar(sol.make)传奇('Balanced',,,,'Highn',,,,'Location',,,,'eastoutside')title('Amount Made')子图(3,1,2)bar(sol.sell)传说('Balanced',,,,'Highn',,,,'Location',,,,'eastoutside')title(“出售金额”)subplot(3,1,3) bar(sol.inventory) legend('Balanced',,,,'Highn',,,,'Location',,,,'eastoutside')title(“存储的金额”)xlabel('时间'end
Profit: 2.24739e+06
productionPlanT=12×6桌makeBalanced makeHighN sellBalanced sellHighN storeBalanced storeHighN ____________ _________ ____________ _________ _____________ __________ January 1100 100 750 300 550 0 February 600 310 800 310 350 0 March 550 650 900 600 0 50 April 850 350 850 400 0 0 May 700 350 700 350 0 0 June 700 300700 300 0 0 7月700 200 700 200 0 0 0 8月600 200 600 200 0 0 9月600 200 600 200 0 0 10月550 200 550 200 550 200 0 0 NOVEMBER 550 200 550 200 0 0 12月750 400 550 200 200 200 200 200 200

图包含3个轴对象。轴对象1带有标题量的对象包含2个类型bar的对象。这些对象表示平衡,高。出售标题量的轴对象2包含2个类型栏的对象。这些对象表示平衡,高。轴对象3具有标题量的存储量包含2个类型bar的对象。这些对象表示平衡,高。

Related Topics