Пример показывает, как включать производную информацию в нелинейную основанную на проблеме оптимизацию. Включая градиенты или Гессиан в оптимизации может принести следующую пользу:
Больше устойчивых результатов. Конечные шаги дифференцирования иногда достигают точек, где цель или нелинейная ограничительная функция являются неопределенными, не конечными, или комплексными.
Аналитические градиенты могут быть более точными, чем оценки конечной разности.
Включая Гессиан может привести к более быстрой сходимости, означая меньше итераций.
Аналитические градиенты могут быть быстрее, чтобы вычислить, чем оценки конечной разности, специально для проблем с разреженной структурой. Для сложных выражений, однако, аналитические градиенты могут быть медленнее, чтобы вычислить.
Несмотря на эти преимущества, подход, основанный на проблеме в настоящее время не использует производную информацию. Чтобы использовать производные в основанной на проблеме оптимизации, преобразуйте свою проблему с помощью prob2struct
, и отредактируйте получившуюся цель и ограничительные функции.
Создайте основанную на проблеме нелинейную оптимизацию. С 2D контрольными переменными x
и y
, используйте целевую функцию
Включайте ограничение что сумма квадратов x
и y
не больше, чем 4.
fun2
не рациональная функция его аргументов. Поэтому, чтобы включать его в задачу оптимизации, необходимо преобразовать его в выражение оптимизации с помощью fcn2optimexpr
.
prob = optimproblem; x = optimvar('x',2); y = optimvar('y',2); fun1 = 100*(x(2) - x(1)^2)^2 + (1 - x(1))^2; fun2 = @(x,y)-exp(-sum((x - y).^2))*exp(-exp(-y(1)))*sech(y(2)); prob.Objective = fun1 + fcn2optimexpr(fun2,x,y); prob.Constraints.cons = sum(x.^2 + y.^2) <= 4;
Чтобы включать производные, преобразуйте проблему в структуру с помощью prob2struct
.
problem = prob2struct(prob);
Во время преобразования, prob2struct
создает файлы функции, которые представляют объективные и нелинейные ограничительные функции. По умолчанию эти функции имеют имена 'generatedObjective.m'
и 'generatedConstraints.m'
.
Вычислите производные, сопоставленные с объективными и нелинейными ограничительными функциями. Если у вас есть лицензия Symbolic Math Toolbox™, можно использовать gradient
или jacobian
функционируйте, чтобы помочь вычислить производные. Смотрите, что Symbolic Math Toolbox Вычисляет Градиенты и Гессианы.
Основанный на решателе подход имеет одну контрольную переменную. Каждая переменная оптимизации (x
или y
, в этом примере), фрагмент контрольной переменной.
Можно найти отображение между переменными оптимизации и одной контрольной переменной в сгенерированном файле целевой функции, 'generatedObjective.m'
. Начало файла содержит эти строки кода:
%% Variable indices. idx_x = [1 2]; idx_y = [3 4]; %% Map solver-based variables to problem-based. x = inputVariables(idx_x); x = x(:); y = inputVariables(idx_y); y = y(:);
В этом коде контрольная переменная имеет имя inputVariables
.
В качестве альтернативы можно найти отображение при помощи varindex
.
idx = varindex(prob); disp(idx.x)
1 2
disp(idx.y)
3 4
Если вы знаете отображение, можно использовать стандартное исчисление, чтобы найти следующие выражения для градиента grad
из целевой функции objective = fun1 + fun2
относительно контрольной переменной [x(:);y(:)]
.
где
Чтобы включать расчетные градиенты в файл целевой функции, отредактируйте 'generatedObjective.m'
можно следующим образом.
%% Insert gradient calculation here. % If you include a gradient, notify the solver by setting the % SpecifyObjectiveGradient option to true. if nargout > 1 c = exp(-sum((x - y).^2)); d = c*exp(-exp(-y(1)))*sech(y(2)); sigma1 = 2*(x(1) - y(1))*d; sigma2 = 2*(x(2) - y(2))*d; grad = zeros(4,1); grad(1) = 2*x(1) - 400*x(1)*(x(2) - x(1)^2) + sigma1 - 2; grad(2) = 200*x(2) - 200*x(1)^2 + sigma2; grad(3) = -sigma1 - d*exp(-y(1)); grad(4) = -sigma2 + d*tanh(y(2)); end
Вспомните, что нелинейным ограничением является x(1)^2 + x(2)^2 + y(1)^2 + y(2)^2 <= 4
. Безусловно, градиентом этой ограничительной функции является 2*[x;y]
. Чтобы включать расчетные градиенты нелинейного ограничения, отредактируйте 'generatedConstraints.m'
можно следующим образом.
%% Insert gradient calculation here. % If you include a gradient, notify the solver by setting the % SpecifyConstraintGradient option to true. if nargout > 2 cineqGrad = 2*[x;y]; ceqGrad = []; end
Запустите проблему с помощью и основанных на проблеме и основанных на решателе методов, чтобы видеть различия. Чтобы запустить проблему с помощью производной информации, создайте подходящие варианты в структуре задачи.
options = optimoptions('fmincon','SpecifyObjectiveGradient',true,... 'SpecifyConstraintGradient',true); problem.options = options;
Нелинейные проблемы требуют непустого x0
поле в структуре задачи.
x0 = [-1;2;1;-1]; problem.x0 = x0;
Вызовите fmincon
на структуре задачи.
[xsolver,fvalsolver,exitflagsolver,outputsolver] = fmincon(problem)
Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. <stopping criteria details> xsolver = 0.8671 0.7505 1.0433 0.5140 fvalsolver = -0.5500 exitflagsolver = 1 outputsolver = struct with fields: iterations: 46 funcCount: 77 constrviolation: 0 stepsize: 7.4091e-06 algorithm: 'interior-point' firstorderopt: 7.5203e-07 cgiterations: 9 message: '↵Local minimum found that satisfies the constraints.↵↵Optimization completed because the objective function is non-decreasing in ↵feasible directions, to within the value of the optimality tolerance,↵and constraints are satisfied to within the value of the constraint tolerance.↵↵<stopping criteria details>↵↵Optimization completed: The relative first-order optimality measure, 7.520304e-07,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.↵↵'
Сравните это решение с тем, полученным из solve
, который не использует производной информации.
init.x = x0(1:2); init.y = x0(3:4); [xproblem,fvalproblem,exitflagproblem,outputproblem] = solve(prob,init)
Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. <stopping criteria details> xproblem = struct with fields: x: [2×1 double] y: [2×1 double] fvalproblem = -0.5500 exitflagproblem = OptimalSolution outputproblem = struct with fields: iterations: 48 funcCount: 276 constrviolation: 0 stepsize: 7.9340e-07 algorithm: 'interior-point' firstorderopt: 6.5496e-07 cgiterations: 9 message: '↵Local minimum found that satisfies the constraints.↵↵Optimization completed because the objective function is non-decreasing in ↵feasible directions, to within the value of the optimality tolerance,↵and constraints are satisfied to within the value of the constraint tolerance.↵↵<stopping criteria details>↵↵Optimization completed: The relative first-order optimality measure, 6.549635e-07,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.↵↵' solver: 'fmincon'
Оба решения сообщают о том же значении функции точности отображения, и оба требуют примерно того же количества итераций (46 информации о градиенте использования, 48 без). Однако решение с помощью градиентов требует только 77 функциональных оценок, по сравнению с 276 для решения без градиентов.