범위 제약 조건이 있는 2차 계획법: 문제 기반
이 예제에서는 2차 목적 함수를 갖는 스케일링 가능한 범위 제약 조건 문제를 정식화하고 푸는 방법을 보여줍니다. 또한 몇 가지 알고리즘에서의 해의 동작도 보여줍니다. 이 문제는 임의 개수의 변수를 포함할 수 있습니다. 변수의 개수가 스케일에 해당합니다. 이 예제의 솔버 기반 버전은 범위 제약 조건을 사용한 2차 최소화 항목을 참조하십시오.
목적 함수는 문제 변수의 개수 n의 함수로서 다음과 같습니다.
문제 만들기
400개의 성분을 갖는 문제 변수 x를 만듭니다. 또한 목적 함수에 대한 표현식 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 = 20, cg iterations = 1813
켤레 기울기 반복이 여러 번 있었습니다.
효율성 증대를 위해 옵션 조정하기
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' 알고리즘을 사용하여 구한 해와 비교합니다. '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.897338, 0.898801, 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.001116.
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.036007.
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.