Main Content

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

Related Topics