You will now expand the model from the previous session to include multiple time periods. A new period index is introduced into the model to cover these time periods and then update the various vectors that have been affected to account for the new domain.
In order to update your model to include a multiple period, you will need to create an index that represents that time period. This type of index is called a period index. After you have defined your period index, you can then use it to update data, variable and constraint vectors to include a specified time period. Examples of period indexes might include: months, quarters, and years.
When you are upgrading a model from a single period to multiple periods, the sales for a specific period may differ from the amount produced in that same period. As a result, a new variable is needed that represents how much needs to be sold, and a new variable that represents the inventory level for each period.
In many cases, there is a fixed cost per period involved with storing inventory. In other cases, however, the cost might not be connected to the actual storing of the inventory, but rather with the stocking and removing of the products from the inventory storage, through the labor costs involved. This means you would need more variables to the model, one for stocking the products, and another for removing them from the inventory.
As it is not possible to sell more of the products than you have on hand, the inventory variable is used to connect the production variables to the sales variables. This is done through a type of constraint, typically called a balance constraint. Balance constraints are used to ensure that quantities going into an entity equal the quantities going out.
A typical inventory balance constraint, Stipulates that the total production, plus the inventory level from the previous period, equals the amount sold, plus how much you leave in the inventory. An example of an inventory balance constraint is:
Produce + Inventory[month-1] = Sales + Inventory
In this case, the entity being balanced is the inventory. The Invt[month-1] is a notation used in MPL to represent the previous period. When working with an inventory where a cost needs to be applied to the stocking and removing of the inventory, you will need define two balance constraints. For example:
Produce + OutInvt = Sales + PutInvt PutInvt + Inventory[month-1] = OutInvt + Inventory
If you think of the plant as an entity, in the first constraint we are balancing what goes into the plant with what goes out. In the same manner, the second constraint balances what goes in to, and what goes out of the inventory.
In many cases the model developer needs to specify a specific initial or ending inventory for the planning period. MPL by default excludes entries the Inventory[month-1] for month equal to zero. There are several ways you can specify a starting inventory, for example you can enter the constraint in two parts as follows:
INDEX month := (Jan, Feb, Mar, Apr) DATA StartInvt := 450 SUBJECT TO InitInvt[month=Jan]: produce + StartInvt = sales + Inventory InvtBal [month>Jan]: produce + Inventory[month-1] = sales + Inventory
This will create a balance constraint for the month of January with starting inventory of 450 units. There are other ways of including a starting inventory in MPL that does not require you to duplicate the constraint, for example with subindexes, but this is the simplest way to formulate these kind of constraints.
In this session, you will create the new model formulation for a multi-period production planning model. You will use the model you created in Session 3, and make the necessary additions and updates to it.
In this new problem, you have a planning period of four months, from January to April. You need to create an index that contains the four months mentioned, and then update the rest of the model accordingly, by adding the index to the defined vectors.
As in the problem in Session 3, the selling price for each product is still $120.00, $100.00, $115.00, respectively. Now, instead of having a single demand for each product, you have a separate demand for each product and each month, as given in the table below:
Production Demand | Jan | Feb | Mar | Apr |
---|---|---|---|---|
A1 | 4300 | 4200 | 6400 | 5300 |
A2 | 4500 | 5400 | 6500 | 7200 |
A3 | 5400 | 6700 | 7800 | 8200 |
The production rate and the production cost remain the same, as given in the table in Session 3. Notice that the production days available are different for each month with 23 days for January, 20 for February, 23 for March and 22 for April.
You will be introducing inventory into the model, therefore, you have the inventory cost for each product with A1 $3.50/month , A2 -$4.00/month and A3 - $3.00/month, respectively.
Each product takes up the same amount of space, but the total inventory capacity is now 800 units per month.
Listed below is the entire model formulation for Planning4. As you can see the model has expanded somewhat from Session 3. The additions to the model are highlighted in boldface in order to make it easy for you to see the changes.
TITLE Production_Planning4; INDEX product := (A1, A2, A3); month := (Jan, Feb, Mar, Apr); DATA Price[product] := (120.00, 100.00, 115.00); Demand[product, month] := (4300, 4200, 6400, 5300, 4500, 5400, 6500, 7200, 5400, 6700, 7800, 8200); ProdCost[product] := (73.30, 52.90, 65.40); ProdRate[product] := (500, 450, 550); ProdDaysAvail[month] := (23, 20, 23, 22); InvtCost[product] := (3.50, 4.00, 3.00); InvtCapacity := 800; VARIABLES Produce[product, month] -> Prod; Inventory[product,month] -> Invt; Sales[product, month] -> Sale; MACROS TotalRevenue := SUM(product, month: Price * Sales); TotalProdCost := SUM(product, month: ProdCost * Produce); TotalInvtCost := SUM(product, month: InvtCost * Inventory); TotalCost := TotalProdCost + TotalInvtCost; MODEL MAX Profit = TotalRevenue - TotalCost; SUBJECT TO ProdCapacity[month] -> PCap: SUM(product: Produce / ProdRate) <= ProdDaysAvail; InvtBal[product, month] -> IBal: Produce + Inventory[month-1] = Sales + Inventory; MaxInventory[month] -> MaxI: SUM(product: Inventory) <= InvtCapacity; BOUNDS Sales <= Demand; END
Start the MPL application.
Choose File | Open and open the model from the previous sessionPlanning3.mpl.
Choose File | Save As to save it as a new model filePlanning4.mpl.
Change the title for the model to reflect that you are working with the Planning4 model:
TITLE Production_Planning4;
In this example, there is a planning period of four months. Create a new index called month. This index will have four elements Jan, Feb, Mar, and Apr, to represent the four month planning period. Add the following definition for the month index, that is highlighted in boldface, to the INDEX section:
INDEX product := (A1, A2, A3); month := (Jan, Feb, Mar, Apr);
In the DATA section, most of the data definitions are the same as in Session 3. One of the data vectors; Demand, needs to be upgraded to include the month index, as it now has different data values for each month. The values for this vector are given in the table in the problem description earlier in this session. Add the index month to the declaration for the Demand data vector, followed with a list of data values as shown below:
DATA Price[product] := (120.00, 100.00, 115.00); Demand[product,month] := (4300, 4200, 6400, 5300, 4500, 5400, 6500, 7200, 5400, 6700, 7800, 8200);
The data constant ProdDaysAvail now has a different value for each month, as does the Demand data vector. This means it needs to be upgraded from a data constant to a one dimensional data vector, with the month as the index. Using the list of production days available, found in the problem description earlier in this session, update the ProdDaysAvail as follows:
ProdCost[product] := (73.30, 52.90, 65.40); ProdRate[product] := (500, 450, 550); ProdDaysAvail[month] := (23, 20, 23, 22);
The problem description defined a cost for each product stored in inventory and a limit on how much can be stored in the inventory. Therefore, in order to represent this, add one more data vector to the model; InvtCost, and also a new data constant, InvtCapacity. At the end of the DATA section add the following definitions:
InvtCost[product] := (3.50, 4.00, 3.00); InvtCapacity := 800;
With this model there are two new variables, Sales and Inventory, that need to be introduced into the model. The Sales variable is used to represent how much of each product is sold each month. The Inventory variable is used to represent how much of each product is stored, each month. The Produce variable needs to be upgraded to include the index month as different amounts of each product are produced, each month. In the model add the following definitions to the VARIABLES section:
VARIABLES Produce[product, month] -> Prod; Inventory[product,month] -> Invt; Sales[product, month] -> Sale;
As in the previous model, the name that appears after the '->' (read becomes) sign is an optional abbreviation of the vector name. This is used to offset the variable name size limitations of many LP solvers.
In the model from the previous session, the total revenue and the total production cost are included in the objective function. Now you need to update this objective function with the index; month, and add an entry for the total inventory cost. As in the previous session, you will continue to use macros to represent each summation.
When calculating the total revenue, you will need to refer to the Sales variable instead of the Produce variable and add the index month to the summation. For the total production cost, you will also need to upgrade the summation to include the month index. The total inventory cost will be defined, as the inventory cost, times the inventory level, for each product and month.
To make the changes in the MACROS section, replace the Produce variable with the Sales variable, update the total revenue and the total production cost summations to include the month index, and add a new macro definition for the total inventory cost as follows:
MACROS TotalRevenue := SUM(product, month: Price * Sales); TotalProdCost := SUM(product, month: ProdCost * Produce); TotalInvtCost := SUM(product, month: InvtCost * Inventory); TotalCost := TotalProdCost + TotalInvtCost;
Please note that the macro for the total production cost has been renamed to TotalProdCost. Another new macro; TotalCost, has been added where you can sum together these two macros to get the total cost. This allows the objective function definition to remain unchanged:
MODEL MAX Profit = TotalRevenue - TotalCost;
In the production capacity constraint, add the index month to the constraint definition and the rest of the constraint remains the same.
SUBJECT TO ProdCapacity[month] -> PCap: SUM(product: Produce / ProdRate) <= ProdDaysAvail;
Please note that in MPL you do not have to enter each index subscript when referring to the data and variable vectors. This means you can easily add more indexes to constraints without having to change how you refer to each vector.
The addition of the Inventory variable to the model needs to include a standard inventory balance constraint. This constraint ranges over each product and each month, specifying that the production, plus the inventory from the month before, is equal to the amount sold, plus the inventory for the current month. Add the following InvtBal constraint below the previous ProdCapacity constraint:
InvtBal[product, month] -> IBal: Produce + Inventory[month-1] = Sales + Inventory;
When entering previous time periods, as in this case the month before, MPL allows you to use expressions such as [month-1].
There is a limit on how much inventory space is available. Therefore, you need to add an inventory capacity constraint to the model. In the problem description, you were told that each product takes up an equal amount of space in inventory and that you can add, or sum over, all of the products to get the total inventory space used. Add the following constraint definition to the model:
MaxInventory[month] -> MaxI: SUM(product: Inventory) <= InvtCapacity;
In the maximum demand upper bound you need to update it to include the Sales variable instead of the Produce variable as shown here below:
BOUNDS Sales <= Demand;
After you have finished entering the model, you should save it by choosing Save from the File menu.
The next step is to solve the Planning4 model, by choosing Solve CPLEX from the Run menu. If you have entered the data correctly, MPL will display the message Optimal Solution Found. If there is an error message window, with a syntax error, please check the formulation you entered with the model detailed earlier in this session.
After solving the model MPL automatically creates a standard solution file named 'Planning4.sol'. You can display the solution file in a view window by pressing the View button at the bottom of the Status Window. A full listing of the solution file is shown below:
MPL Modeling System - Copyright (c) 1988-2001, Maximal Software, Inc. -------------------------------------------------------------------------------- MODEL STATISTICS Problem name: Production_Planning4 Filename: Planning4.mpl Date: April 17, 1998 Time: 22:52 Parsing time: 0.15 sec Solver: CPLEX Objective value: 2246007.27273 Iterations: 26 Solution time: 0.04 sec Constraints: 20 Variables: 36 Nonzeros: 69 Density: 10 % SOLUTION RESULT Optimal solution found MAX Profit = 2246007.2727 MACROS Macro Name Values ----------------------------------------------- TotalRevenue 5386045.4545 TotalProdCost 3139078.1818 TotalInvtCost 960.0000 TotalCost 3140038.1818 ----------------------------------------------- DECISION VARIABLES VARIABLE Produce[product,month] : product month Activity Reduced Cost ---------------------------------------------------- A1 Jan 4300.0000 0.0000 A1 Feb 4200.0000 0.0000 A1 Mar 4409.0909 0.0000 A1 Apr 3545.4545 0.0000 A2 Jan 1800.0000 0.0000 A2 Feb 0.0000 -3.6667 A2 Mar 0.0000 -4.7889 A2 Apr 0.0000 -0.7889 A3 Jan 5720.0000 0.0000 A3 Feb 6380.0000 0.0000 A3 Mar 7800.0000 0.0000 A3 Apr 8200.0000 0.0000 ---------------------------------------------------- VARIABLE Inventory[product,month] : product month Activity Reduced Cost ---------------------------------------------------- A1 Jan 0.0000 -0.2000 A1 Feb 0.0000 -2.4900 A1 Mar 0.0000 -3.5000 A1 Apr 0.0000 -123.5000 A2 Jan 0.0000 -4.0000 A2 Feb 0.0000 -4.0000 A2 Mar 0.0000 0.0000 A2 Apr 0.0000 -108.0000 A3 Jan 320.0000 0.0000 A3 Feb 0.0000 -2.0818 A3 Mar 0.0000 -3.0000 A3 Apr 0.0000 -110.8545 ---------------------------------------------------- VARIABLE Sales[product,month] : product month Activity Reduced Cost ---------------------------------------------------- A1 Jan 4300.0000 4.3100 A1 Feb 4200.0000 1.0100 A1 Mar 4409.0909 0.0000 A1 Apr 3545.4545 0.0000 A2 Jan 1800.0000 0.0000 A2 Feb 0.0000 0.0000 A2 Mar 0.0000 0.0000 A2 Apr 0.0000 -4.0000 A3 Jan 5400.0000 11.0636 A3 Feb 6700.0000 8.0636 A3 Mar 7800.0000 7.1455 A3 Apr 8200.0000 7.1455 ---------------------------------------------------- CONSTRAINTS CONSTRAINT ProdCapacity[month] : month Slack Shadow Price ------------------------------------------- Jan 0.0000 -21195.0000 Feb 0.0000 -22845.0000 Mar 0.0000 -23350.0000 Apr 0.0000 -23350.0000 ------------------------------------------- CONSTRAINT InvtBal[product,month] : product month Slack Shadow Price ---------------------------------------------------- A1 Jan 0.0000 115.6900 A1 Feb 0.0000 118.9900 A1 Mar 0.0000 120.0000 A1 Apr 0.0000 120.0000 A2 Jan 0.0000 100.0000 A2 Feb 0.0000 100.0000 A2 Mar 0.0000 100.0000 A2 Apr 0.0000 104.0000 A3 Jan 0.0000 103.9364 A3 Feb 0.0000 106.9364 A3 Mar 0.0000 107.8545 A3 Apr 0.0000 107.8545 ---------------------------------------------------- CONSTRAINT MaxInventory[month] : month Slack Shadow Price ------------------------------------------- Jan 480.0000 0.0000 Feb 800.0000 0.0000 Mar 800.0000 0.0000 Apr 800.0000 0.0000 ------------------------------------------- END
According to the solution, the profit is now $2.2M which is considerably higher than in the Planning3 model, as we are now working with four months. This comes from a total revenue of $5.4M and a total cost of $3.1M, most of which is the production cost, as we keep a very low inventory just for January.
If you look at the Produce variable in the solution, you will notice that we are producing products A1 and A3 for the whole planning period, although not always up to the full demand. Product A2, on the other hand, is only produced 1800 units in January, as we do not have enough capacity to produce all three of the products.
In January, the model decided to produce extra 320 units of A3, above the required demand, in order to put enough into inventory to satisfy the demand in February.