lsqlin
Создайте псевдослучайные данные для задачи минимизации нормы C*x – d
удовлетворяющее границам и линейным ограничениям неравенства. Создайте задачу для 15 переменных, удовлетворяющих границам lb = –1
и ub = 1
и с учетом 150 линейных ограничений A*x <= b
.
N = 15; % Number of variables rng default % For reproducibility A = randn([10*N,N]); b = 5*ones(size(A,1),1); Aeq = []; % No equality constraints beq = []; ub = ones(N,1); lb = -ub; C = 10*eye(N) + randn(N); C = (C + C.')/2; % Symmetrize the matrix d = 20*randn(N,1);
lsqlin
Генерация кода требует 'active-set'
алгоритм, который требует начальной точки x0
. Чтобы решить проблему в MATLAB® использование алгоритма, требуемого для генерации кода, установка опций и начальная точка.
x0 = zeros(size(d)); options = optimoptions('lsqlin','Algorithm','active-set');
Чтобы решить проблему, позвоните lsqlin
.
[x,fv,~,ef,output,lam] = lsqlin(C,d,A,b,Aeq,beq,lb,ub,x0,options);
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.
После lsqlin
решает эту задачу, посмотрите на количество ненулевых множителей Лагранжа каждого типа. Посмотрите, сколько компонентов решения не ограничено ограничениями путем вычитания общего количества ненулевых множителей Лагранжа.
nl = nnz(lam.lower); nu = nnz(lam.upper); ni = nnz(lam.ineqlin); nunconstrained = N - nl - nu - ni; fprintf('Number of solution components at lower bounds: %g\n',nl); fprintf('Number of solution components at upper bounds: %g\n',nu); fprintf('Number of solution components at inequality: %g\n',ni); fprintf('Number of unconstrained solution components: %g\n',nunconstrained);
Number of solution components at lower bounds: 3 Number of solution components at upper bounds: 2 Number of solution components at inequality: 5 Number of unconstrained solution components: 5
Чтобы решить ту же проблему с помощью генерации кода, выполните следующие шаги.
Написание функции, которая включает все предыдущие шаги. Чтобы получить меньше выходных данных, установите Display
опция для 'off'
.
function [x,fv,lam] = solvelsqlin N = 15; % Number of variables rng default % For reproducibility A = randn([10*N,N]); b = 5*ones(size(A,1),1); Aeq = []; % No equality constraints beq = []; ub = ones(N,1); lb = -ub; C = 10*eye(N) + randn(N); C = (C + C.')/2; % Symmetrize the matrix d = 20*randn(N,1); x0 = zeros(size(d)); options = optimoptions('lsqlin','Algorithm','active-set',... 'Display','off'); [x,fv,~,ef,output,lam] = lsqlin(C,d,A,b,Aeq,beq,lb,ub,x0,options); nl = nnz(lam.lower); nu = nnz(lam.upper); ni = nnz(lam.ineqlin); nunconstrained = N - nl - nu - ni; fprintf('Number of solution components at lower bounds: %g\n',nl); fprintf('Number of solution components at upper bounds: %g\n',nu); fprintf('Number of solution components at inequality: %g\n',ni); fprintf('Number of unconstrained solution components: %g\n',nunconstrained); end
Создайте строение для генерации кода. В этом случае используйте 'mex'
.
cfg = coder.config('mex');
Сгенерируйте код для solvelsqlin
функция.
codegen -config cfg solvelsqlin
Протестируйте сгенерированный код, запустив сгенерированный файл с именем solvelsqlin_mex.mexw64
или аналогичный.
[x2,fv2,lam2] = solvelsqlin_mex;
Number of solution components at lower bounds: 1 Number of solution components at upper bounds: 5 Number of solution components at inequality: 6 Number of unconstrained solution components: 3
Количество компонентов решения в различных границах изменилось по сравнению с предыдущим решением. Чтобы увидеть, являются ли эти различия важными, сравните разности точек решения и разности значений функции.
disp([norm(x - x2), abs(fv - fv2)])
1.0e-12 * 0.0007 0.2274
Различия между этими двумя решениями незначительны.
lsqlin
| optimoptions
| quadprog
| codegen
(MATLAB CODER)