Этот пример показывает, как сформулировать и решить масштабируемую связанную с ограничениями задачу с квадратичной целевой функцией. Пример показывает поведение решения с помощью нескольких алгоритмов. Задача может иметь любое количество переменных; количество переменных - шкала. Для версии этого примера, основанной на решателе, см. «Квадратичная минимизация с связанными ограничениями».
Целевая функция, как функция от количества переменных задачи n,
Создайте переменные задачи с именем x
который имеет 400 компонентов. Кроме того, создайте выражение с именем objec
для целевой функции. Связать каждую переменную ниже на 0 и выше на 0,9, за исключением случаев, когда разрешено быть неограниченным.
n = 400; x = optimvar('x',n,'LowerBound',0,'UpperBound',0.9); x(n).LowerBound = -Inf; x(n).UpperBound = Inf; prevtime = 1:n-1; nexttime = 2:n; objec = 2*sum(x.^2) - 2*sum(x(nexttime).*x(prevtime)) - 2*x(1) - 2*x(end);
Создайте задачу оптимизации с именем qprob
. Включите целевую функцию в задачу.
qprob = optimproblem('Objective',objec);
Создайте опции, которые задают quadprog
'trust-region-reflective'
алгоритм и отсутствие отображения. Создайте начальную точку, приблизительно центрированную между границами.
opts = optimoptions('quadprog','Algorithm','trust-region-reflective','Display','off'); x0 = 0.5*ones(n,1); x00 = struct('x',x0);
Решите проблему.
[sol,qfval,qexitflag,qoutput] = solve(qprob,x00,'options',opts);
Постройте график решения.
plot(sol.x,'b-') xlabel('Index') ylabel('x(index)')
Сообщите о флаге выхода, количестве итераций и количестве сопряженных итераций градиента.
fprintf('Exit flag = %d, iterations = %d, cg iterations = %d\n',... double(qexitflag),qoutput.iterations,qoutput.cgiterations)
Exit flag = 3, iterations = 19, cg iterations = 1636
Было много сопряженных итераций градиента.
Уменьшите количество сопряженных итераций градиента путем установки SubproblemAlgorithm
опция для 'factorization'
. Эта опция заставляет решатель использовать более дорогой метод внутреннего решения, который устраняет сопряженные градиентные шаги, для чистой общей экономии времени в этом случае.
opts.SubproblemAlgorithm = 'factorization'; [sol2,qfval2,qexitflag2,qoutput2] = solve(qprob,x00,'options',opts); fprintf('Exit flag = %d, iterations = %d, cg iterations = %d\n',... double(qexitflag2),qoutput2.iterations,qoutput2.cgiterations)
Exit flag = 3, iterations = 10, cg iterations = 0
Количество итераций и сопряженных градиентных итераций уменьшилось.
'interior-point'
РешениеСравните эти решения с решениями, полученными с помощью 'interior-point'
по умолчанию алгоритм. The
'interior-point'
алгоритм не использует начальную точку, поэтому не проходите x00
на solve
.
opts = optimoptions('quadprog','Algorithm','interior-point-convex','Display','off'); [sol3,qfval3,qexitflag3,qoutput3] = solve(qprob,'options',opts); fprintf('Exit flag = %d, iterations = %d, cg iterations = %d\n',... double(qexitflag3),qoutput3.iterations,0)
Exit flag = 1, iterations = 8, cg iterations = 0
middle = floor(n/2); fprintf('The three solutions are slightly different.\nThe middle component is %f, %f, or %f.\n',... sol.x(middle),sol2.x(middle),sol3.x(middle))
The three solutions are slightly different. The middle component is 0.896278, 0.898676, or 0.857389.
fprintf('The relative norm of sol - sol2 is %f.\n',norm(sol.x-sol2.x)/norm(sol.x))
The relative norm of sol - sol2 is 0.001997.
fprintf('The relative norm of sol2 - sol3 is %f.\n',norm(sol2.x-sol3.x)/norm(sol2.x))
The relative norm of sol2 - sol3 is 0.035894.
fprintf(['The three objective function values are %f, %f, and %f.\n' ... 'The ''interior-point'' algorithm is slightly less accurate.'],qfval,qfval2,qfval3)
The three objective function values are -1.985000, -1.985000, and -1.984963. The 'interior-point' algorithm is slightly less accurate.