Problem

The problem is “to blend steels with various chemical compositions to obtain 25 tons of steel with a specific chemical composition. The result should have 5% carbon and 5% molybdenum by weight. The objective is to minimize the cost for blending the steel”. The problem is from MatLab Doc.

Modeling Steps

A set i ∈ I of different ingots of steel are available for purchase. Only one of each ingot type
is available. Their weight is w_{i}, the carbon and molybdenum contents in percentage is given by
r_{i} and m_{i}, and the cost per ton is c_{i}.

Furthermore, a set j ∈ J of grades of alloy steel and one grade of scrap steel are available for
purchase. Alloy and scrap steels can be purchased in fractional amounts. the carbon and
molybdenum contents in percentage of each alloy is given by ra_{i} and ma_{i}, and the cost per ton
is ca_{i}. The scrap content of the carbon and molybdenum in percentage is rs and ms and its cost
per ton is cs.

Let I_{i} be the number of ingots, A_{j} the fractional weight of each alloy, and S the weight of scrap.
So, how many ingots and how much alloy and scrap must be used to produce W tons of steel
with a p% of carbon and molybdenum while minimizing the total costs. The model can be
formulated as follows:

Further Comments

In the first formulation, the MatLab formulation is copied one-to-one to LPL. MatLab is matrix-base. Indices are not needed. In LPL, passive indices can be omitted if the context allows it. MatLab does not make a distiction between parameters and expression, like LPL does. MatLab uses a package optimproblem to specify the problem.

The second formulation of both modeling languages is closer to their “style”. In MatLab, a single function intlinprog defines a complete integer linear model, The parameters are prepared in advance as data matrices. In LPL, the model consists of the common strucure: set, parameter, variable, constraint and objective function.

LPL code (first formulation) (run mixing)

model mixing "Steel Blending";

set i,Ingot := [1..4];

set j, Alloy := [1..3];

variable alloys{j}; scrap;

binary ingots{i};

parameter weightIngots{i}:=[5,3,4,6];

uCostIngots{i}:=[350,330,310,280];

costIngots{i}:=weightIngots*uCostIngots;

costAlloys{j}:=[500,450,400];

costScrap:=100;

expression cost: sum{i} costIngots*ingots + sum{j} costAlloys*alloys + costScrap*scrap;

expression totalWeight: sum{i} weightIngots*ingots + sum{j} alloys + scrap;

parameter carbonIngots{i} := [5,4,5,3];

carbonAlloys{j} := [8,7,6];

carbonScrap := 3;

expression totalCarbon: sum{i}weightIngots*carbonIngots/100*ingots + sum{j}carbonAlloys/100*alloys + carbonScrap/100*scrap;

parameter molybIngots{i}:= [3,3,4,4];

molybAlloys{j} := [6,7,8];

molybScrap := 9;

expression totalMolyb: sum{i}weightIngots*molybIngots/100*ingots + sum{j}molybAlloys/100*alloys + molybScrap/100*scrap;

constraint conswt: totalWeight = 25;

conscarb: totalCarbon = 1.25;

consmolyb: totalMolyb = 1.25;

minimize C: cost;

Writep(ingots,alloys,scrap,cost);

end

MatLab code (first formulation) (download mixing.m)

prob = optimproblem;

ingots = optimvar('ingots',4,'Type','integer','LowerBound',0,'UpperBound',1);

alloys = optimvar('alloys',3,'LowerBound',0);

scrap = optimvar('scrap','LowerBound',0);

weightIngots = [5,3,4,6];

costIngots = weightIngots.*[350,330,310,280];

costAlloys = [500,450,400];

costScrap = 100;

cost = costIngots*ingots + costAlloys*alloys + costScrap*scrap;

prob.Objective = cost;

totalWeight = weightIngots*ingots + sum(alloys) + scrap;

carbonIngots = [5,4,5,3]/100;

carbonAlloys = [8,7,6]/100;

carbonScrap = 3/100;

totalCarbon = (weightIngots.*carbonIngots)*ingots + carbonAlloys*alloys + carbonScrap*scrap;

molybIngots = [3,3,4,4]/100;

molybAlloys = [6,7,8]/100;

molybScrap = 9/100;

totalMolyb = (weightIngots.*molybIngots)*ingots + molybAlloys*alloys + molybScrap*scrap;

prob.Constraints.conswt = totalWeight == 25;

prob.Constraints.conscarb = totalCarbon == 1.25;

prob.Constraints.consmolyb = totalMolyb == 1.25;

[sol,fval] = solve(prob);

sol.ingots

sol.alloys

sol.scrap

fval

LPL code (second formulation) (run mixing1)

model mixing "Steel Blending I";

set i,Ingot := [1..4];

j, Alloy := [1,2,3,scrap];

parameter weightIngots{i}:=[5,3,4,6];

uCostIngots{i}:=[350,330,310,280];

costAlloys{j}:=[500,450,400,100];

carbonIngots{i} := [5,4,5,3];

carbonAlloys{j} := [8,7,6,3];

molybIngots{i}:= [3,3,4,4];

molybAlloys{j} := [6,7,8,9];

variable A{j}; binary I{i};

constraint conswt:

sum{i} weightIngots*I + sum{j} A = 25;

conscarb: sum{i}weightIngots*carbonIngots/100*I + sum{j}carbonAlloys/100*A = 1.25;

consmolyb: sum{i}weightIngots*molybIngots/100*I + sum{j}molybAlloys/100*A = 1.25;

minimize cost: sum{i} weightIngots*uCostIngots*I + sum{j} costAlloys*A;

Writep(I,A,cost);

end

MatLab code (second formulation) (download mixing1.m)

f = [350*5,330*3,310*4,280*6,500,450,400,100];

intcon = 1:4;

A = [];

b = [];

Aeq = [5,3,4,6,1,1,1,1;

5*0.05,3*0.04,4*0.05,6*0.03,0.08,0.07,0.06,0.03;

5*0.03,3*0.03,4*0.04,6*0.04,0.06,0.07,0.08,0.09];

beq = [25;1.25;1.25];

lb = zeros(8,1);

ub = ones(8,1);

ub(5:end) = Inf; % No upper bound on noninteger variables

[x,fval] = intlinprog(f,intcon,A,b,Aeq,beq,lb,ub);

x,fval % print the solution