Try our new documentation site (beta).
Filter Content By
Version
Text Search
${sidebar_list_label} - Back
Filter by Language
gc_pwl_func.m
function gc_pwl_func % Copyright 2024, Gurobi Optimization, LLC % % This example considers the following nonconvex nonlinear problem % % maximize 2 x + y % subject to exp(x) + 4 sqrt(y) <= 9 % x, y >= 0 % % We show you two approaches to solve this: % % 1) Use a piecewise-linear approach to handle general function % constraints (such as exp and sqrt). % a) Add two variables % u = exp(x) % v = sqrt(y) % b) Compute points (x, u) of u = exp(x) for some step length (e.g., x % = 0, 1e-3, 2e-3, ..., xmax) and points (y, v) of v = sqrt(y) for % some step length (e.g., y = 0, 1e-3, 2e-3, ..., ymax). We need to % compute xmax and ymax (which is easy for this example, but this % does not hold in general). % c) Use the points to add two general constraints of type % piecewise-linear. % % 2) Use the Gurobis built-in general function constraints directly (EXP % and POW). Here, we do not need to compute the points and the maximal % possible values, which will be done internally by Gurobi. In this % approach, we show how to "zoom in" on the optimal solution and % tighten tolerances to improve the solution quality. % % Four nonneg. variables x, y, u, v, one linear constraint u + 4*v <= 9 m.varnames = {'x', 'y', 'u', 'v'}; m.lb = zeros(4, 1); m.ub = +inf(4, 1); m.A = sparse([0, 0, 1, 4]); m.rhs = 9; % Objective m.modelsense = 'max'; m.obj = [2; 1; 0; 0]; % First approach: PWL constraints % Approximate u \approx exp(x), equispaced points in [0, xmax], xmax = log(9) m.genconpwl(1).xvar = 1; m.genconpwl(1).yvar = 3; m.genconpwl(1).xpts = 0:1e-3:log(9); m.genconpwl(1).ypts = exp(m.genconpwl(1).xpts); % Approximate v \approx sqrt(y), equispaced points in [0, ymax], ymax = (9/4)^2 m.genconpwl(2).xvar = 2; m.genconpwl(2).yvar = 4; m.genconpwl(2).xpts = 0:1e-3:(9/4)^2; m.genconpwl(2).ypts = sqrt(m.genconpwl(2).xpts); % Solve and print solution result = gurobi(m); printsol(result.objval, result.x(1), result.x(2), result.x(3), result.x(4)); % Second approach: General function constraint approach with auto PWL % translation by Gurobi % Delete explicit PWL approximations from model m = rmfield(m, 'genconpwl'); % Set u \approx exp(x) m.genconexp.xvar = 1; m.genconexp.yvar = 3; m.genconexp.name = 'gcf1'; % Set v \approx sqrt(y) = y^0.5 m.genconpow.xvar = 2; m.genconpow.yvar = 4; m.genconpow.a = 0.5; m.genconpow.name = 'gcf2'; % Parameters for discretization: use equal piece length with length = 1e-3 params.FuncPieces = 1; params.FuncPieceLength = 1e-3; % Solve and print solution result = gurobi(m, params); printsol(result.objval, result.x(1), result.x(2), result.x(3), result.x(4)); % Zoom in, use optimal solution to reduce the ranges and use a smaller % pclen=1-5 to resolve m.lb(1) = max(m.lb(1), result.x(1) - 0.01); m.ub(1) = min(m.ub(1), result.x(1) + 0.01); m.lb(2) = max(m.lb(2), result.x(2) - 0.01); m.ub(2) = min(m.ub(2), result.x(2) + 0.01); params.FuncPieceLength = 1e-5; % Solve and print solution result = gurobi(m, params); printsol(result.objval, result.x(1), result.x(2), result.x(3), result.x(4)); end function printsol(objval, x, y, u, v) fprintf('x = %g, u = %g\n', x, u); fprintf('y = %g, v = %g\n', y, v); fprintf('Obj = %g\n', objval); % Calculate violation of exp(x) + 4 sqrt(y) <= 9 vio = exp(x) + 4 * sqrt(y) - 9; if vio < 0 vio = 0; end fprintf('Vio = %g\n', vio); end