Main Content

이 번역 페이지는 최신 내용을 담고 있지 않습니다. 최신 내용을 영문으로 보려면 여기를 클릭하십시오.

제약 조건이 있는 비선형 시스템

부등식 제약 조건이 있는 방정식 풀기

fsolve는 비선형 연립방정식을 풉니다. 하지만, 이 함수를 사용하는 경우 범위 제약 조건을 포함하여 어떠한 제약 조건도 포함시킬 수 없습니다. 그렇다면 제약 조건이 있을 때는 비선형 연립방정식을 어떻게 풀 수 있을까요?

제약 조건을 충족하는 해가 존재한다는 보장은 없습니다. 사실 이 문제는 어떠한 해도 가지지 않을 수 있으며 제약 조건을 충족하지 않는 해조차 없을 수도 있습니다. 그럼에도 불구하고 제약 조건을 충족하는 해를 찾는 데 도움이 될 수 있는 기법이 있습니다.

다음 방정식을 푸는 방법을 통해 이 기법을 살펴보겠습니다.

F1(x)=(x1+1)(10-x1)1+x221+x22+x2F2(x)=(x2+2)(20-x2)1+x121+x12+x1,

여기서 x의 성분은 음수가 아니어야 합니다. 이 방정식에는 다음과 같은 네 개의 해가 있습니다.

x=(-1,-2)x=(10,-2)x=(-1,20)x=(10,20).

이 중에서 제약 조건을 충족하는 해는 x = (10,20) 하나뿐입니다.

이 예제의 마지막 부분에 있는 fbnd 헬퍼 함수가 F(x)를 수치적으로 계산합니다.

여러 다른 시작점 사용하기

일반적으로, N개 변수의 N개의 연립방정식에는 고립된(Isolated) 해가 있습니다. 이는 각 해의 근방에는 그 또한 해가 되는 인근 이웃이 없다는 것을 의미합니다. 따라서 제약 조건을 충족하는 해를 찾는 한 가지 방법은 여러 초기점 x0을 생성하고 각 x0에서 시작하여 fsolve를 실행하는 것입니다.

이 예제에서는 연립방정식 F(x)=0의 해를 찾기 위해 평균이 0이고 표준편차가 100인 정규분포를 갖는 임의의 점 10개를 사용합니다.

rng default % For reproducibility
N = 10; % Try 10 random start points
pts = 100*randn(N,2); % Initial points are rows in pts
soln = zeros(N,2); % Allocate solution
opts = optimoptions('fsolve','Display','off');
for k = 1:N
    soln(k,:) = fsolve(@fbnd,pts(k,:),opts); % Find solutions
end

제약 조건을 충족하는 해를 나열합니다.

idx = soln(:,1) >= 0 & soln(:,2) >= 0;
disp(soln(idx,:))
   10.0000   20.0000
   10.0000   20.0000
   10.0000   20.0000
   10.0000   20.0000
   10.0000   20.0000

다른 여러 알고리즘 사용하기

fsolve에는 3가지 알고리즘이 있습니다. 알고리즘마다 서로 다른 해를 도출할 수 있습니다.

이 예제에서는 x0 = [1,9]를 사용하여 각 알고리즘이 반환하는 해를 검토합니다.

x0 = [1,9];
opts = optimoptions(@fsolve,'Display','off',...
    'Algorithm','trust-region-dogleg');
x1 = fsolve(@fbnd,x0,opts)
x1 = 1×2

   -1.0000   -2.0000

opts.Algorithm = 'trust-region';
x2 = fsolve(@fbnd,x0,opts)
x2 = 1×2

   -1.0000   20.0000

opts.Algorithm = 'levenberg-marquardt';
x3 = fsolve(@fbnd,x0,opts)
x3 = 1×2

    0.9523    8.9941

여기서는 세 가지 알고리즘 모두 동일한 초기점에 대해 각기 다른 해를 구합니다. 어떤 해도 제약 조건을 충족하지 않습니다. 보고된 "해" x3은 해가 아니라 국소 정상점(stationary point)일 뿐입니다.

범위가 있는 lsqnonlin 사용하기

lsqnonlin은 벡터 함수 F(x)의 성분에 대한 제곱합을 최소화하려고 합니다. 따라서, 방정식 F(x) = 0을 풀려고 시도합니다. 또한, lsqnonlin은 범위 제약 조건을 받습니다.

lsqnonlin의 예제 문제를 정식화한 후 풀어봅니다.

lb = [0,0];
rng default
x0 = 100*randn(2,1);
[x,res] = lsqnonlin(@fbnd,x0,lb)
Local minimum found.

Optimization completed because the size of the gradient is less than
the value of the optimality tolerance.
x = 2×1

   10.0000
   20.0000

res = 2.4783e-25

이 경우, lsqnonlin은 제약 조건을 충족하는 해로 수렴됩니다. Global Optimization Toolbox의 MultiStart 솔버와 함께 lsqnonlin을 사용하면 많은 초기점에서 자동으로 탐색을 수행할 수 있습니다. MultiStart Using lsqcurvefit or lsqnonlin (Global Optimization Toolbox) 항목을 참조하십시오.

방정식과 부등식을 fmincon 제약 조건으로 설정하기

다음과 같이 문제를 다시 정식화하고 fmincon을 사용할 수 있습니다.

  • x에 대해 @(x)0처럼 0으로 계산되는 상수 목적 함수를 제공합니다.

  • fsolve 목적 함수를 fmincon에서 비선형 등식 제약 조건으로 설정합니다.

  • 일반적인 fmincon 구문에 그 밖의 다른 제약 조건을 제공합니다.

이 예제의 마지막 부분에 있는 fminconstr 헬퍼 함수는 비선형 제약 조건을 구현합니다. 제약 조건이 있는 문제를 풉니다.

lb = [0,0]; % Lower bound constraint
rng default % Reproducible initial point
x0 = 100*randn(2,1);
opts = optimoptions(@fmincon,'Algorithm','interior-point','Display','off');
x = fmincon(@(x)0,x0,[],[],[],[],lb,[],@fminconstr,opts)
x = 2×1

   10.0000
   20.0000

이 경우, fmincon은 시작점에서 문제를 풉니다.

헬퍼 함수

다음 코드는 fbnd 헬퍼 함수를 생성합니다.

function F = fbnd(x)

F(1) = (x(1)+1)*(10-x(1))*(1+x(2)^2)/(1+x(2)^2+x(2));
F(2) = (x(2)+2)*(20-x(2))*(1+x(1)^2)/(1+x(1)^2+x(1));
end

다음 코드는 fminconstr 헬퍼 함수를 생성합니다.

function [c,ceq] = fminconstr(x)

c = []; % No nonlinear inequality
ceq = fbnd(x); % fsolve objective is fmincon nonlinear equality constraints
end

참고 항목

| |

관련 항목