Separate Optimization Model from Data
To obtain a scalable, reusable optimization problem, create the problem in a way that separates the problem data from the model structure.
Suppose that you have a multiperiod scheduling problem with several products. The time
periods are in a vector, periods
, and the products are in a string
vector, products
.
periods = 1:10; products = ["strawberry","cherry","red grape",... "green grape","nectarine","apricot"];
To create variables that represent the number of products used in each period, use statements that take sizes from the data. For example:
usage = optimvar('usage',length(periods),products,... 'Type','integer','LowerBound',0);
To later change the time periods or products, you need to change the data only in
periods
and products
. You can then run the
same code to create usage
.
In other words, to maintain flexibility and allow for reuse, do not use a statement that has hard-coded data sizes. For example:
usage = optimvar('usage',10,6,... % DO NOT DO THIS 'Type','Integer','LowerBound',0);
The same consideration holds for expressions as well as variables. Suppose that the
costs for the products are in a data matrix, costs
, of size
length(periods)
-by-length(products)
. To
simulate valid data, create a random integer matrix of the appropriate size.
rng default % For reproducibility costs = randi(8,length(periods),length(products));
The best practice is to create cost expressions that take sizes from the data.
costPerYear = sum(costs.*usage,2); totalCost = sum(costPerYear);
In this way, if you ever change the data sizes, the statements that create
costPerYear
and totalCost
do not change. In
other words, to maintain flexibility and allow for reuse, do not use a statement that
has hard-coded data sizes. For example:
costPerYear = optimexpr(10,1); % DO NOT DO THIS totalcost = 0; for yr = 1:10 % DO NOT DO THIS costPerYear(i) = sum(costs(i,:).*usage(i,:)); totalcost = totalcost + costPerYear(i); end