Skip to content

Commit a78ea0f

Browse files
committed
Add MILP example from examples/miqp_ex1.m to MILP tests.
1 parent e9e6ba1 commit a78ea0f

3 files changed

Lines changed: 139 additions & 2 deletions

File tree

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ since version 5.0
66
-----------------
77

88
#### 10/21/25
9+
- Add MILP example from `examples/miqp_ex1.m` to MILP tests.
910
- Fix typo bug in dimension checking in `set_params()` for quadratic costs.
1011

1112
#### 10/3/25

lib/t/t_mm_solve_miqps.m

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function t_mm_solve_miqps(quiet)
2626
does_miqp(1) = 1;
2727
end
2828

29-
n = 33;
29+
n = 51;
3030
nmiqp = 20;
3131
nmiqp_soln = 30;
3232
diff_tool = 'bbdiff';
@@ -150,6 +150,74 @@ function t_mm_solve_miqps(quiet)
150150
t_is([x([1;2;4;5]); x(3)+x(6)], [0; 0; 0; 0; 5.2], 7, [t 'x']);
151151
t_is(f, 15.6, 7, [t 'f']);
152152

153+
%% from milp_ex1.m
154+
PlantCapacity = [ 60; 60 ]; % Plants 1, 2
155+
CustomerDemandY = [ 10; 15; 5 ]; % Customers 1, 2, 3
156+
CustomerDemandZ = [ 8; 12; 6 ]; % Customers 1, 2, 3
157+
DeliveryCostY = [
158+
4 7; % Customer 1
159+
5 6; % Customer 2
160+
3 8 % Customer 3
161+
];
162+
DeliveryCostZ = [
163+
10 4; % Customer 1
164+
9 5; % Customer 2
165+
12 3 % Customer 3
166+
];
167+
PlantFixedCost = [
168+
100 100 50; % Plant 1
169+
200 100 120 % Plant 2
170+
];
171+
Scenario = 1; % build scenario 1 initially
172+
mm = mp.opt_model();
173+
mm.var.add('u', 2, [], 0, 1, 'B');
174+
mm.var.init_indexed_name('y', {2});
175+
mm.var.init_indexed_name('z', {2});
176+
for p = 1:2
177+
mm.var.add('y', {p}, 3, [], 0); % Product Y, Plant p to Customers 1-3
178+
mm.var.add('z', {p}, 3, [], 0); % Product Z, Plant p to Customers 1-3
179+
end
180+
mm.qdc.add(mm.var, 'fixed', [], PlantFixedCost(:, Scenario), [], {'u'});
181+
mm.qdc.init_indexed_name('delivery_y', {2});
182+
mm.qdc.init_indexed_name('delivery_z', {2});
183+
for p = 1:2
184+
vs_y = struct('name', 'y', 'idx', {{p}}); % variable set for 'y{p}'
185+
vs_z = struct('name', 'z', 'idx', {{p}}); % variable set for 'z{p}'
186+
mm.qdc.add(mm.var, 'delivery_y', {p}, [], DeliveryCostY(:, p), [], vs_y);
187+
mm.qdc.add(mm.var, 'delivery_z', {p}, [], DeliveryCostZ(:, p), [], vs_z);
188+
end
189+
Au = -spdiags(PlantCapacity, 0, 2, 2);
190+
Ayz = sparse([1 1 1 1 1 1 0 0 0 0 0 0; % sum for plant 1
191+
0 0 0 0 0 0 1 1 1 1 1 1]); % sum for plant 2
192+
ub = 0; % constraint upper bound (no lower bound)
193+
mm.lin.add(mm.var, 'capacity', [Au Ayz], [], ub);
194+
vs_y = struct('name', 'y', 'idx', {{1}, {2}});
195+
Ad = [speye(3) speye(3)];
196+
mm.lin.add(mm.var, 'demand_y', Ad, CustomerDemandY, CustomerDemandY, vs_y);
197+
vs_z = struct('name', 'z', 'idx', {{1}, {2}});
198+
mm.lin.add(mm.var, 'demand_z', Ad, CustomerDemandZ, CustomerDemandZ, vs_z);
199+
ef = [ 490 1130/3 540;
200+
410 1000/3 440;
201+
410 317 410 ];
202+
ex = [ 1 0 10 15 5 8 12 6 0 0 0 0 0 0;
203+
0 1 0 0 0 0 0 0 10 15 5 8 12 6;
204+
1 1 10 15 5 0 0 0 0 0 0 8 12 6;
205+
0.5 1.3/3 10 15 5 0 0 0 0 0 0 8 12 6]';
206+
for Scenario = 1:3
207+
t = sprintf('%s - 14-d MILP Scenario %d: ', names{k}, Scenario);
208+
mm.qdc.set_params(mm.var, 'fixed', 'c', PlantFixedCost(:, Scenario));
209+
[x, f, s, out, lam] = mm.solve(opt);
210+
t_is(s, 1, 12, [t 'exitflag']);
211+
t_is(x, ex(:, Scenario), 12, [t 'x']);
212+
t_is(f, ef(Scenario, 1), 12, [t 'f']);
213+
214+
t = sprintf('%s - 14-d MILP Scenario %d (integer relaxed) : ', names{k}, Scenario);
215+
[x, f, s, out, lam] = mm.solve(opt_r);
216+
t_is(s, 1, 12, [t 'exitflag']);
217+
t_is(x, ex(:, 4), 12, [t 'x']);
218+
t_is(f, ef(Scenario, 2), 12, [t 'f']);
219+
end
220+
153221
if does_miqp(k)
154222
t = sprintf('%s - 4-d MIQP : ', names{k});
155223
%% from cplexmiqpex.m, CPLEX_Studio_Academic124/cplex/examples/src/matlab/cplexmiqpex.m

lib/t/t_om_solve_miqps.m

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function t_om_solve_miqps(quiet)
2626
does_miqp(1) = 1;
2727
end
2828

29-
n = 33;
29+
n = 51;
3030
nmiqp = 20;
3131
nmiqp_soln = 30;
3232
diff_tool = 'bbdiff';
@@ -150,6 +150,74 @@ function t_om_solve_miqps(quiet)
150150
t_is([x([1;2;4;5]); x(3)+x(6)], [0; 0; 0; 0; 5.2], 7, [t 'x']);
151151
t_is(f, 15.6, 7, [t 'f']);
152152

153+
%% from milp_ex1.m
154+
PlantCapacity = [ 60; 60 ]; % Plants 1, 2
155+
CustomerDemandY = [ 10; 15; 5 ]; % Customers 1, 2, 3
156+
CustomerDemandZ = [ 8; 12; 6 ]; % Customers 1, 2, 3
157+
DeliveryCostY = [
158+
4 7; % Customer 1
159+
5 6; % Customer 2
160+
3 8 % Customer 3
161+
];
162+
DeliveryCostZ = [
163+
10 4; % Customer 1
164+
9 5; % Customer 2
165+
12 3 % Customer 3
166+
];
167+
PlantFixedCost = [
168+
100 100 50; % Plant 1
169+
200 100 120 % Plant 2
170+
];
171+
Scenario = 1; % build scenario 1 initially
172+
om = opt_model();
173+
om.add_var('u', 2, [], 0, 1, 'B');
174+
om.var.init_indexed_name('y', {2});
175+
om.var.init_indexed_name('z', {2});
176+
for p = 1:2
177+
om.var.add('y', {p}, 3, [], 0); % Product Y, Plant p to Customers 1-3
178+
om.var.add('z', {p}, 3, [], 0); % Product Z, Plant p to Customers 1-3
179+
end
180+
om.qdc.add(om.var, 'fixed', [], PlantFixedCost(:, Scenario), [], {'u'});
181+
om.qdc.init_indexed_name('delivery_y', {2});
182+
om.qdc.init_indexed_name('delivery_z', {2});
183+
for p = 1:2
184+
vs_y = struct('name', 'y', 'idx', {{p}}); % variable set for 'y{p}'
185+
vs_z = struct('name', 'z', 'idx', {{p}}); % variable set for 'z{p}'
186+
om.qdc.add(om.var, 'delivery_y', {p}, [], DeliveryCostY(:, p), [], vs_y);
187+
om.qdc.add(om.var, 'delivery_z', {p}, [], DeliveryCostZ(:, p), [], vs_z);
188+
end
189+
Au = -spdiags(PlantCapacity, 0, 2, 2);
190+
Ayz = sparse([1 1 1 1 1 1 0 0 0 0 0 0; % sum for plant 1
191+
0 0 0 0 0 0 1 1 1 1 1 1]); % sum for plant 2
192+
ub = 0; % constraint upper bound (no lower bound)
193+
om.lin.add(om.var, 'capacity', [Au Ayz], [], ub);
194+
vs_y = struct('name', 'y', 'idx', {{1}, {2}});
195+
Ad = [speye(3) speye(3)];
196+
om.lin.add(om.var, 'demand_y', Ad, CustomerDemandY, CustomerDemandY, vs_y);
197+
vs_z = struct('name', 'z', 'idx', {{1}, {2}});
198+
om.lin.add(om.var, 'demand_z', Ad, CustomerDemandZ, CustomerDemandZ, vs_z);
199+
ef = [ 490 1130/3 540;
200+
410 1000/3 440;
201+
410 317 410 ];
202+
ex = [ 1 0 10 15 5 8 12 6 0 0 0 0 0 0;
203+
0 1 0 0 0 0 0 0 10 15 5 8 12 6;
204+
1 1 10 15 5 0 0 0 0 0 0 8 12 6;
205+
0.5 1.3/3 10 15 5 0 0 0 0 0 0 8 12 6]';
206+
for Scenario = 1:3
207+
t = sprintf('%s - 14-d MILP Scenario %d: ', names{k}, Scenario);
208+
om.qdc.set_params(om.var, 'fixed', 'c', PlantFixedCost(:, Scenario));
209+
[x, f, s, out, lam] = om.solve(opt);
210+
t_is(s, 1, 12, [t 'exitflag']);
211+
t_is(x, ex(:, Scenario), 12, [t 'x']);
212+
t_is(f, ef(Scenario, 1), 12, [t 'f']);
213+
214+
t = sprintf('%s - 14-d MILP Scenario %d (integer relaxed) : ', names{k}, Scenario);
215+
[x, f, s, out, lam] = om.solve(opt_r);
216+
t_is(s, 1, 12, [t 'exitflag']);
217+
t_is(x, ex(:, 4), 12, [t 'x']);
218+
t_is(f, ef(Scenario, 2), 12, [t 'f']);
219+
end
220+
153221
if does_miqp(k)
154222
t = sprintf('%s - 4-d MIQP : ', names{k});
155223
%% from cplexmiqpex.m, CPLEX_Studio_Academic124/cplex/examples/src/matlab/cplexmiqpex.m

0 commit comments

Comments
 (0)