Linear programming: a product mix problem
Describes the problem and presents the model and data files.
As a first example, let’s consider a simple mathematical programming (MP) problem to determine an optimal production mix.
To meet the demands of its customers, a company manufactures its products in its own factories (inside production) or buys them from other companies (outside production). Inside production is subject to some resource constraints: each product consumes a certain amount of each resource. In contrast, outside production is theoretically unlimited. The problem is to determine how much of each product should be produced inside the company and how much outside, while minimizing the overall production cost, meeting the demand, and not exceeding the resource constraints.
The statement of the problem must specify the set of products and the set of resources. For each product, we need to know the inside and outside production costs, and for each resource we need to know the available capacity of that resource. Finally, we need to know the consumption of resources by the different products.
This is a general outline of an optimization problem. The production example illustrates a specific pasta manufacturing problem. The project contains a model, product.mod, shown in the example below, which states the problem to be solved. The data to be used by the model is also shown below, in the fileproduct.dat.
A pasta manufacturing problem (product.mod)
{string} Products = ...;
{string} Resources = ...;
tuple productData {
float demand;
float insideCost;
float outsideCost;
float consumption[Resources];
}
productData Product[Products] = ...;
float Capacity[Resources] = ...;
dvar float+ Inside[Products];
dvar float+ Outside[Products];
execute CPX_PARAM {
cplex.preind = 0;
cplex.simdisplay = 2;
}
minimize
sum( p in Products )
(Product[p].insideCost * Inside[p] +
Product[p].outsideCost * Outside[p] );
subject to {
forall( r in Resources )
ctInside:
sum( p in Products )
Product[p].consumption[r] * Inside[p] <= Capacity[r];
forall( p in Products )
ctDemand:
Inside[p] + Outside[p] >= Product[p].demand;
}
Data for the pasta manufacturing problem (product.dat)
Products = { "kluski", "capellini", "fettuccine" };
Resources = { "flour", "eggs" };
Product = #[
kluski : < 100, 0.6, 0.8, [ 0.5, 0.2 ] >,
capellini : < 200, 0.8, 0.9, [ 0.4, 0.4 ] >,
fettuccine : < 300, 0.3, 0.4, [ 0.3, 0.6 ] >
]#;
Capacity = [ 20, 40 ];
In the model, the instruction
tuple productData {
float demand;
float insideCost;
float outsideCost;
float consumption[Resources];
}
declares a tuple type with four fields. The first three
fields, of type float, are used to represent
the demand and costs of a product; the last field is an array representing
the resource consumptions of the product. These fields are intended
to hold all the data related to a given product.
The instruction
ProductData product[Products] = ...;
declares an array of these tuples, one for each product.
The model also contains two arrays of decision variables to represent the inside and outside production, respectively. There is an objective function to minimize the total production cost, and there are two types of constraints: a set of constraints to avoid exceeding the capacity limitation, and another set of constraints to satisfy the demand requirements.
Initialization of the data given in product.dat for
one instance of this problem specifies these various data items: to
initialize the tuples, values are given for each of their fields.
Product = #[
kluski : < 100, 0.6, 0.8, [ 0.5, 0.2 ] >,
capellini : < 200, 0.8, 0.9, [ 0.4, 0.4 ] >,
fettuccine : < 300, 0.3, 0.4, [ 0.3, 0.6 ] >
]#;
In the data file we use a set of strings called Products to represent the varieties of pasta and
another set of strings called Resources to
represent the raw ingredients of flour and eggs.