Skip to content

Commit 42baaf8

Browse files
committed
Update fix_integer implementation to explicitly eliminate the fixed variables.
1 parent d3bde4c commit 42baaf8

File tree

1 file changed

+63
-41
lines changed

1 file changed

+63
-41
lines changed

lib/miqps_master.m

Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@
239239
end
240240

241241
%% handle relax_integer and fix_integer options
242+
done = false;
243+
fix_integer_presolve = true;
242244
if ~isempty(vtype) && (isfield(opt, 'relax_integer') && opt.relax_integer || ...
243245
isfield(opt, 'fix_integer') && opt.fix_integer)
244246
nx = length(x0);
@@ -247,54 +249,74 @@
247249
end
248250
j = (vtype == 'B' | vtype == 'I')';
249251
if isfield(opt, 'fix_integer') && opt.fix_integer
250-
%% fix integer variables
251-
if ~isempty(j)
252-
%% expand if necessary
253-
if length(xmin) == 1
254-
xmin = xmin * ones(nx, 1);
255-
elseif isempty(xmin)
256-
xmin = -Inf(nx, 1);
257-
end
258-
if length(xmax) == 1
259-
xmax = xmax * ones(nx, 1);
260-
elseif isempty(xmax)
261-
xmax = Inf(nx, 1);
252+
if fix_integer_presolve
253+
x = x0;
254+
Axj = A(:,j) * x(j);
255+
[x(~j), f, eflag, output, lambda] = ...
256+
qps_master(H(~j, ~j), c(~j) + (H(~j,j)+H(j,~j)') * x(j), ...
257+
A(:, ~j), l-Axj, u-Axj, xmin(~j), xmax(~j), x(~j), opt);
258+
f = f + (x(j)' * H(j,j) + c(j)') * x(j);
259+
mu_lower = zeros(size(x));
260+
mu_upper = zeros(size(x));
261+
mu_lower(~j) = lambda.lower;
262+
mu_upper(~j) = lambda.upper;
263+
lambda.lower = mu_lower;
264+
lambda.upper = mu_upper;
265+
done = true;
266+
else
267+
%% fix integer variables
268+
if ~isempty(j)
269+
%% expand if necessary
270+
if length(xmin) == 1
271+
xmin = xmin * ones(nx, 1);
272+
elseif isempty(xmin)
273+
xmin = -Inf(nx, 1);
274+
end
275+
if length(xmax) == 1
276+
xmax = xmax * ones(nx, 1);
277+
elseif isempty(xmax)
278+
xmax = Inf(nx, 1);
279+
end
280+
xmin(j) = x0(j);
281+
xmax(j) = x0(j);
262282
end
263-
xmin(j) = x0(j);
264-
xmax(j) = x0(j);
265283
end
266284
end
267-
vtype(j) = 'C';
285+
if ~done
286+
vtype(j) = 'C';
287+
end
268288
end
269289

270290
%%----- call the appropriate solver -----
271-
switch alg
272-
case 'CPLEX'
273-
[x, f, eflag, output, lambda] = ...
274-
miqps_cplex(H, c, A, l, u, xmin, xmax, x0, vtype, opt);
275-
case 'GLPK'
276-
[x, f, eflag, output, lambda] = ...
277-
miqps_glpk(H, c, A, l, u, xmin, xmax, x0, vtype, opt);
278-
case 'GUROBI'
279-
[x, f, eflag, output, lambda] = ...
280-
miqps_gurobi(H, c, A, l, u, xmin, xmax, x0, vtype, opt);
281-
case 'MOSEK'
282-
[x, f, eflag, output, lambda] = ...
283-
miqps_mosek(H, c, A, l, u, xmin, xmax, x0, vtype, opt);
284-
case 'OT'
285-
[x, f, eflag, output, lambda] = ...
286-
miqps_ot(H, c, A, l, u, xmin, xmax, x0, vtype, opt);
287-
case 'HIGHS'
288-
[x, f, eflag, output, lambda] = ...
289-
miqps_highs(H, c, A, l, u, xmin, xmax, x0, vtype, opt);
290-
otherwise
291-
fcn = ['miqps_' lower(alg)];
292-
if exist([fcn '.m']) == 2
291+
if ~done
292+
switch alg
293+
case 'CPLEX'
293294
[x, f, eflag, output, lambda] = ...
294-
feval(fcn, H, c, A, l, u, xmin, xmax, x0, vtype, opt);
295-
else
296-
error('miqps_master: ''%s'' is not a valid algorithm code', alg);
297-
end
295+
miqps_cplex(H, c, A, l, u, xmin, xmax, x0, vtype, opt);
296+
case 'GLPK'
297+
[x, f, eflag, output, lambda] = ...
298+
miqps_glpk(H, c, A, l, u, xmin, xmax, x0, vtype, opt);
299+
case 'GUROBI'
300+
[x, f, eflag, output, lambda] = ...
301+
miqps_gurobi(H, c, A, l, u, xmin, xmax, x0, vtype, opt);
302+
case 'MOSEK'
303+
[x, f, eflag, output, lambda] = ...
304+
miqps_mosek(H, c, A, l, u, xmin, xmax, x0, vtype, opt);
305+
case 'OT'
306+
[x, f, eflag, output, lambda] = ...
307+
miqps_ot(H, c, A, l, u, xmin, xmax, x0, vtype, opt);
308+
case 'HIGHS'
309+
[x, f, eflag, output, lambda] = ...
310+
miqps_highs(H, c, A, l, u, xmin, xmax, x0, vtype, opt);
311+
otherwise
312+
fcn = ['miqps_' lower(alg)];
313+
if exist([fcn '.m']) == 2
314+
[x, f, eflag, output, lambda] = ...
315+
feval(fcn, H, c, A, l, u, xmin, xmax, x0, vtype, opt);
316+
else
317+
error('miqps_master: ''%s'' is not a valid algorithm code', alg);
318+
end
319+
end
298320
end
299321
if ~isfield(output, 'alg') || isempty(output.alg)
300322
output.alg = alg;

0 commit comments

Comments
 (0)