The company Minorette produces two types of large toy lorries for children: blue removal vans and red tank lorries. Each of these lorries is assembled from thirteen items. See Figure8.1for the breakdown of components (also called a Gozinto graph or Parts explosion) and the following Table8.6for the prices of the components.
Table 8.6: Prices of components
Wheel Steel bar Bumper Chassis Cabin Door window BC 0.30 BC 1 BC 0.20 BC 0.80 BC 2.75 BC 0.10 Windscreen Blue container Red tank Blue motor Red motor Headlight
BC 0.29 BC 2.60 BC 3 BC 1.65 BC 1.65 BC 0.15 Blue lorry (or red) Assembled chassis Door window Cabin Wheel Chassis Blue motor (or red) Blue container
(or red tank)
Assembled cabin Windscreen Steel bar 2 1 2 2 1 1 1 1 1 2 1 2 1 Headlight Axle Bumper
Figure 8.1:Breakdown of components (Gozinto graph)
The subsets (axles, chassis, blue or red cabin) may be assembled by the company using the components, or subcontracted. The following table lists the costs for assembling and for subcontracting these subsets, together with the capacities of the company. The assembly costs do not take into account the buying prices of their components.
Table 8.7:Subcontracting and assembly costs, assembly capacities
Axle Assembled chassis Assembled cabin Blue lorry Red lorry
Subcontracting BC 12.75 BC 30 BC 3 – –
Assembly BC 6.80 BC 3.55 BC 3.20 BC 2.20 BC 2.60
Capacity 600 4000 3000 4000 5000
For the next month, Minorette has the same demand forecast of 3000 pieces for the two types of lorries. At present, the company has no stock. Which quantities of the different items should Minorette buy or subcontract to satisfy the demand while minimizing the production cost?
8.3.1
Model formulation
Let ITEMS be the complete set of all products with the subsets FINAL of final products, ASMBL of products resulting from assembly, and PREPROD of products used in the assembly of others. We write REQqpfor the requirement of component p in the assembly of q. For instance, for an axle we need two wheels and one steel bar, that is REQaxle,wheel= 2 and REQaxle,steelbar= 1.
Let CBUYpbe the price paid when buying item p. Since subcontracting a product means buying it from its producer, we consider that this cost is the price for buying a preproduct that is not assembled and is the cost of subcontracting for the assembled pieces.
We write CPRODp for the cost of assembling a product p. The variables that we need to determine are the quantities to produce producepof the assembled products p and those to buy (or subcontract) buyp
of every preproduct p. This gives the following mathematical model: minimize X p∈PREPROD CBUYp· buyp+ X p∈ASMBL CPRODp· producep (8.3.1)
∀p ∈ FINAL : producep≥ DEMp (8.3.2)
∀p ∈ PREPROD : (8.3.3)
p ∈ ASMBL : buyp+ producep≥
X q∈ASMBL REQqp· produceq p 6∈ ASMBL : buyp≥ X q∈ASMBL REQqp· produceq
∀p ∈ ASMBL : producep≤ CAPp (8.3.4)
∀p ∈ ASMBL : producep∈IN (8.3.5)
∀p ∈ PREPROD : buyp∈IN (8.3.6)
The objective function (8.3.1) minimizes the production cost, that is, the buying price or cost for sub- contracting and the assembly cost. The constraints (8.3.2) indicate that the produced quantities of the final products (blue and red lorries) must be greater than or equal to the demand DEMp. The constraints (8.3.3) guarantee that the total quantity of item p that is bought or produced is sufficient to produce all articles q that contain p.
The constraints (8.3.4) establish the limits on the assembly capacities CAPpfor every assembled product p. The constraints (8.3.5) and (8.3.6) are the integrality constraints for the variables.
Note that an alternative formulation to the model displayed above consists of defining buying and assem- bly costs for all items: preproducts that cannot be assembled receive the value ‘infinity’ as their assembly cost, and this value is also assigned as the buying price to the final products. With these costs, we may define variables producepand buypfor all products and in the objective function (1) and the constraints (3) simply sum over all variables — the ‘infinity’ cost values force the corresponding variables to take the value 0. Whilst easier to write down, this second formulation introduces large coefficient values into the model that typically lead to numerical instabilities and should therefore be avoided.
8.3.2
Implementation
The following Mosel program implements the mathematical model of lines (8.3.1) to (8.3.6). All data and index sets are defined in the data file and initialized dynamically when executing the program.
model "C-3 Toy production" uses "mmxprs"
declarations
ITEMS: set of string ! Set of all products FINAL: set of string ! Set of final products ASMBL: set of string ! Set of assembled products PREPROD: set of string ! Set of preproducts
CAP: array(ASMBL) of integer ! Capacity of assembly lines DEM: array(FINAL) of integer ! Demand of lorries
CPROD: array(ASMBL) of real ! Assembly costs CBUY: array(ITEMS) of real ! Purchase costs
REQ: array(ASMBL,PREPROD) of integer ! Items req. for assembling a product end-declarations
initializations from ’c3toy.dat’ DEM CBUY REQ
[CPROD, CAP] as ’ASSEMBLY’ end-initializations
finalize(ASMBL); finalize(PREPROD); finalize(FINAL); finalize(ITEMS) declarations
produce: array(ASMBL) of mpvar ! Quantity of items produced buy: array(PREPROD) of mpvar ! Quantity of items bought end-declarations
! Objective: total costs
Cost:=sum(p in PREPROD) CBUY(p)*buy(p) + sum(p in ASMBL) CPROD(p)*produce(p)
! Satisfy demands
forall(p in FINAL) produce(p) >= DEM(p) ! Assembly balance
forall(p in PREPROD) buy(p) + if(p in ASMBL, produce(p), 0) >= sum(q in ASMBL) REQ(q,p)*produce(q) ! Limits on assembly capacity
forall(p in ASMBL) produce(p) <= CAP(p) forall(p in PREPROD) buy(p) is_integer forall(p in ASMBL) produce(p) is_integer ! Solve the problem
minimize(Cost) end-model
As opposed to most other models presented in this book, in this implementation we do not fix the index sets directly in the Mosel program but initialize all data dynamically from file. We only define the variables once the data has been read in and the index sets have been finalized — that is, the arrays of variables are created with fixed sizes. If we defined the variables in the samedeclarationsblock as the data arrays, this array would be created as a dynamic array, just like the data arrays. But unlike the data arrays, in a dynamic array of variables every entry needs to be created explicitly, using the function create. It is therefore also possible to implement the Mosel program as shown below, though it should be noted that the above version with fixed-size arrays is slightly more efficient:
declarations
ITEMS: set of string ! Set of all products FINAL: set of string ! Set of final products ASMBL: set of string ! Set of assembled products PREPROD: set of string ! Set of pre-products CAP: array(ASMBL) of integer ! Capacity of assembly lines DEM: array(FINAL) of integer ! Demand of lorries
CPROD: array(ASMBL) of real ! Assembly costs CBUY: array(ITEMS) of real ! Purchase costs
REQ: array(ASMBL,PREPROD) of integer ! Items req. for assembling a product produce: array(ASMBL) of mpvar ! Quantity of items produced
buy: array(PREPROD) of mpvar ! Quantity of items bought end-declarations
initializations from ’c3toy.dat’ DEM CBUY REQ
[CPROD, CAP] as ’ASSEMBLY’ end-initializations
forall(p in ASMBL) create(produce(p)) forall(p in PREPROD) create(buy(p))
In this example, the data of the arraysCPRODandCAPare contained in a single recordASSEMBLYand these two arrays are therefore read jointly using the keywordasto indicate the label of the record.
8.3.3
Results
The minimum total cost for satisfying the demand of toy lorries isBC238,365. The next two tables summa- rize the quantities of products that are bought, subcontracted, or assembled at the factory.
Table 8.8: Quantities of preproducts bought
Wheel Steel bar Bumper Chassis Cabin Door window
1200 600 600 300 0 0
Windscreen Blue container Red tank Blue motor Red motor Headlight
Table 8.9: Production and subcontracting of assembled products
Axle Assembled chassis Assembled cabin Blue lorry Red lorry
Produce 600 300 0 3000 3000
Subcontract 0 5700 6000 – –