최적화 기준법과 수학적 계획법의 비교 및 활용

최적화 방법의 분류 및 핵심 차이점

다음 표는 최적화 기준법과 수학적 계획법의 주요 특성을 정리한 것입니다.

평가 항목 최적화 기준법 수학적 계획법
기본 개념 공학적 직관과 물리적 원칙 기반 수학 이론과 알고리즘 기반
수렴 성질 빠른 수렴 가능, 국소 최적해에 머무를 수 있음 이론적 수렴 보장, 전역 최적해 탐색 가능
적용 범위 구조 최적화, 토폴로지 최적화 등 특정 분야 중심 다양한 문제 유형에 일반적으로 적용 가능
구현 난이도 상대적으로 간단하고 해석 용이 수학적 배경이 필요함
대표적 기법 만응력 기준, 에너지 최소화 기준 등 경사 하강법, 순차적 2차 계획법 등

최적화 기준법의 원리와 예제

1. 기초 개념

최적화 기준법은 실제 설계 경험과 물리적 최적성 조건을 바탕으로, 반복적인 업데이트 규칙을 통해 해를 도출합니다.

2. 만응력 기준을 이용한 트러스 구조 최적화 예제

function [design_vars, history] = stress_equilibrium_opt()
    % 만응력 기준을 활용한 구조 최적화
    
    num_elements = 12;
    max_iterations = 150;
    tolerance = 1e-7;
    material_density = 8000;  % kg/m³
    element_length = 1.5;      % m
    max_stress = 300e6;        % Pa
    min_stress = -220e6;       % Pa
    
    % 초기 설계 변수 (단면적)
    x = ones(num_elements, 1) * 2e-3;
    lower_bound = 1e-4 * ones(num_elements, 1);
    upper_bound = 5e-2 * ones(num_elements, 1);
    
    history.design = zeros(num_elements, max_iterations);
    history.obj_val = zeros(1, max_iterations);
    history.max_stress_vals = zeros(1, max_iterations);

    for iter = 1:max_iterations
        % 구조 해석: 각 요소의 응력 계산
        stresses = analyze_structure(x);
        
        % 목표 함수: 전체 무게
        total_weight = material_density * element_length * sum(x);
        
        % 만응력 기준에 따른 설계 변수 업데이트
        new_x = zeros(num_elements, 1);
        for i = 1:num_elements
            if stresses(i) > 0
                new_x(i) = x(i) * abs(stresses(i)) / max_stress;
            else
                new_x(i) = x(i) * abs(stresses(i)) / abs(min_stress);
            end
        end
        
        % 경계 조건 적용
        new_x = max(lower_bound, min(upper_bound, new_x));
        
        % 수렴 검사
        if norm(new_x - x) < tolerance
            fprintf('수렴 완료 (반복 횟수: %d)\n', iter);
            break;
        end
        
        % 감쇠 처리 (진동 방지)
        damping = 0.65;
        x = damping * new_x + (1 - damping) * x;
        
        % 기록 저장
        history.design(:, iter) = x;
        history.obj_val(iter) = total_weight;
        history.max_stress_vals(iter) = max(abs(stresses));
        
        fprintf('반복 %d: 무게 = %.4f kg, 최대 응력 = %.2f MPa\n', ...
                iter, total_weight, max(abs(stresses))/1e6);
    end
    
    design_vars = x;
    history.iter_count = iter;
end

function stresses = analyze_structure(x)
    % 단순화된 구조 해석 모델
    n = length(x);
    stresses = zeros(n, 1);
    
    base_load = 1.2e5;  % 기준 하중 (N)
    for i = 1:n
        variation = 0.4 * cos(pi * i / n);
        nominal_stress = base_load / x(i);
        stresses(i) = nominal_stress * (1 + variation);
    end
end

3. 유연도 최소화 기준 (에너지 기준) 예제

function compliance_minimization_example()
    % 유연도 최소화를 위한 최적화 기준법 적용
    
    num_elements = 10;
    max_iter = 60;
    volume_ratio = 0.5;
    
    % 초기 밀도 값 설정
    density = ones(num_elements, 1) * volume_ratio;
    min_density = 0.001;
    
    move_limit = 0.15;
    penalization = 4;  % SIMP 패널티 계수
    
    for iter = 1:max_iter
        % 유연도 및 민감도 계산
        [compliance, sensitivity] = compute_compliance(density, penalization);
        
        % OC 기준을 통한 업데이트
        lambda_low = 0;
        lambda_high = 1e9;
        
        while (lambda_high - lambda_low) / (lambda_low + lambda_high) > 1e-5
            lambda_mid = 0.5 * (lambda_low + lambda_high);
            
            updated_density = max(min_density, ...
                max(density - move_limit, ...
                min(1, min(density + move_limit, ...
                density .* sqrt(-sensitivity / lambda_mid)))));
            
            if sum(updated_density) > volume_ratio * num_elements
                lambda_low = lambda_mid;
            else
                lambda_high = lambda_mid;
            end
        end
        
        density = updated_density;
        
        fprintf('반복 %d: 유연도 = %.6f, 부피 비율 = %.3f\n', ...
                iter, compliance, mean(density));
    end
end

function [C, dC] = compute_compliance(x, p)
    % 유연도 및 그 민감도 계산
    n = length(x);
    
    E = x.^p;  % 재료 강성
    C = sum(1 ./ E);
    dC = -p * x.^(p-1) ./ E.^2;
end

수학적 계획법의 구현 사례

1. 경사 하강법 (Gradient Descent)

function [optimal_x, trace] = gradient_descent_opt()
    % Rosenbrock 함수 최소화
    
    f = @(x) (1 - x(1))^2 + 100*(x(2) - x(1)^2)^2;
    grad = @(x) [2*(x(1)-1) - 400*x(1)*(x(2)-x(1)^2); ...
                 200*(x(2)-x(1)^2)];
    
    max_iter = 2000;
    tol = 1e-9;
    x_init = [-1; 1];
    
    alpha = 1;
    c = 1e-4;
    rho = 0.5;
    
    x = x_init;
    trace.x_path = zeros(2, max_iter);
    trace.f_values = zeros(1, max_iter);
    trace.grad_norm = zeros(1, max_iter);
    
    for iter = 1:max_iter
        g = grad(x);
        f_val = f(x);
        
        trace.x_path(:, iter) = x;
        trace.f_values(iter) = f_val;
        trace.grad_norm(iter) = norm(g);
        
        if norm(g) < tol
            fprintf('수렴: 반복 %d\n', iter);
            break;
        end
        
        % Armijo 조건에 따른 선형 탐색
        while f(x - alpha*g) > f_val - c*alpha*(g'*g)
            alpha = rho * alpha;
        end
        
        x = x - alpha * g;
        
        if mod(iter, 200) == 0
            fprintf('반복 %d: f(x) = %.6f, ||∇f|| = %.6f\n', ...
                    iter, f_val, norm(g));
        end
    end
    
    optimal_x = x;
    trace.iterations = iter;
end

2. 순차적 2차 계획법 (SQP)

function [solution, history] = sequential_quadratic_programming()
    % 제약조건이 있는 최적화 문제 해결
    
    obj_func = @(x) x(1)^2 + x(2)^2;
    grad_obj = @(x) [2*x(1); 2*x(2)];
    hessian_obj = @(x) [2, 0; 0, 2];
    
    constraint1 = @(x) x(1) + x(2) - 1;  % ≥ 0
    constraint2 = @(x) 4 - x(1)^2 - x(2)^2;  % ≥ 0
    
    grad_c1 = @(x) [1; 1];
    grad_c2 = @(x) [-2*x(1); -2*x(2)];
    
    max_iter = 40;
    tol = 1e-6;
    x = [0.5; 0.5];
    lambda = [0; 0];
    
    history.x_seq = zeros(2, max_iter);
    history.obj_seq = zeros(1, max_iter);
    history.violation = zeros(1, max_iter);
    
    for iter = 1:max_iter
        g_f = grad_obj(x);
        H = hessian_obj(x);
        
        g_vals = [constraint1(x); constraint2(x)];
        A = [grad_c1(x)', grad_c2(x)'];
        
        % QP 서브프로블럼 해결
        options = optimoptions('quadprog', 'Display', 'none');
        delta = quadprog(H, g_f, -A, g_vals, [], [], [], [], [], options);
        
        x_new = x + delta;
        lambda_new = -A \ g_f;
        
        if norm(x_new - x) < tol && norm(lambda_new - lambda) < tol
            fprintf('SQP 수렴: 반복 %d\n', iter);
            break;
        end
        
        x = x_new;
        lambda = lambda_new;
        
        history.x_seq(:, iter) = x;
        history.obj_seq(iter) = obj_func(x);
        history.violation(iter) = max(-min(g_vals), 0);
        
        fprintf('반복 %d: f(x) = %.4f, 위반값 = %.6f\n', ...
                iter, obj_func(x), history.violation(iter));
    end
    
    solution = x;
    history.iter_num = iter;
end

3. 내부 점법 (Interior Point Method)

function [opt_point, log_data] = interior_point_optimization()
    % 불등식 제약 최적화 문제 해결
    
    obj = @(x) x(1)^4 + x(2)^4;
    grad_obj = @(x) [4*x(1)^3; 4*x(2)^3];
    hess_obj = @(x) [12*x(1)^2, 0; 0, 12*x(2)^2];
    
    mu_initial = 15;
    mu = mu_initial;
    reduction_factor = 0.2;
    tol = 1e-7;
    max_iter = 100;
    
    x = [0.6; 0.6];  % 내부 점
    log_data.x_path = zeros(2, max_iter);
    log_data.obj_vals = zeros(1, max_iter);
    log_data.mu_vals = zeros(1, max_iter);
    
    for iter = 1:max_iter
        barrier = @(x) obj(x) - mu * (log(x(1)) + log(x(2)) + log(x(1)+x(2)-1));
        grad_barrier = @(x) grad_obj(x) - mu * [1/x(1) + 1/(x(1)+x(2)-1); ...
                                               1/x(2) + 1/(x(1)+x(2)-1)];
        hess_barrier = @(x) hess_obj(x) + mu * [1/x(1)^2 + 1/(x(1)+x(2)-1)^2, 1/(x(1)+x(2)-1)^2; ...
                                                1/(x(1)+x(2)-1)^2, 1/x(2)^2 + 1/(x(1)+x(2)-1)^2];
        
        % 내부 점에서 최적화 (뉴턴법 사용)
        x_next = newton_method(barrier, grad_barrier, hess_barrier, x);
        
        mu = reduction_factor * mu;
        
        if norm(x_next - x) < tol
            fprintf('내부 점법 수렴: 반복 %d\n', iter);
            break;
        end
        
        x = x_next;
        
        log_data.x_path(:, iter) = x;
        log_data.obj_vals(iter) = obj(x);
        log_data.mu_vals(iter) = mu;
        
        fprintf('반복 %d: f(x) = %.6f, μ = %.6f\n', iter, obj(x), mu);
    end
    
    opt_point = x;
    log_data.iterations = iter;
end

function x_final = newton_method(obj_func, grad_func, hess_func, x0)
    max_iter = 25;
    tol = 1e-8;
    x = x0;
    
    for i = 1:max_iter
        g = grad_func(x);
        H = hess_func(x);
        
        if norm(g) < tol
            break;
        end
        
        step = -H \ g;
        
        alpha = 1;
        while obj_func(x + alpha*step) > obj_func(x) + 1e-4 * alpha * g' * step
            alpha = 0.5 * alpha;
        end
        
        x = x + alpha * step;
    end
    
    x_final = x;
end

성능 비교 및 시각화

function performance_comparison()
    % 여러 최적화 방법의 성능 비교
    
    f = @(x) x(1)^2 + x(2)^2 + x(1)*x(2);
    grad_f = @(x) [2*x(1) + x(2); 2*x(2) + x(1)];
    
    initial_points = [-2, 2; 2, -2; -1, -1];
    
    figure('Position', [100, 100, 1400, 900]);
    
    subplot(2, 3, 1);
    [X, Y] = meshgrid(-3:0.1:3, -3:0.1:3);
    Z = arrayfun(@(x,y) f([x,y]), X, Y);
    contour(X, Y, Z, 50, 'LineColor', 'k');
    hold on;
    title('목표 함수 등고선');
    xlabel('x₁'); ylabel('x₂');
    
    method_names = {'경사 하강법', '뉴턴법', '공액 근사법'};
    
    for idx = 1:size(initial_points, 1)
        x0 = initial_points(idx, :)';
        
        for meth_idx = 1:3
            switch meth_idx
                case 1
                    [sol, hist] = run_gradient_descent(f, grad_f, x0);
                    color = 'r';
                case 2
                    [sol, hist] = run_newton_method(f, grad_f, x0);
                    color = 'g';
                case 3
                    [sol, hist] = run_conjugate_gradient(f, grad_f, x0);
                    color = 'b';
            end
            
            subplot(2, 3, 1);
            plot(hist.x_path(1, 1:hist.iter), hist.x_path(2, 1:hist.iter), ...
                 [color, '-o'], 'LineWidth', 1.2, 'MarkerSize', 4);
            
            subplot(2, 3, meth_idx + 1);
            semilogy(1:hist.iter, hist.obj_values, [color], 'LineWidth', 2);
            title([method_names{meth_idx}, ' 수렴 곡선']);
            xlabel('반복 횟수'); ylabel('목표 함수 값');
            grid on;
        end
    end
    
    subplot(2, 3, 1);
    legend('등고선', 'GD-경로1', 'Newton-경로1', 'CG-경로1', ...
           'GD-경로2', 'Newton-경로2', 'CG-경로2', ...
           'GD-경로3', 'Newton-경로3', 'CG-경로3', 'Location', 'best');
end

적용 지침

  • 최적화 기준법 사용 시:

  • 설계 원리가 명확하고 물리적 해석이 가능한 경우

  • 빠른 실행과 실용적인 해가 요구되는 경우

  • 구조 최적화, 재료 배치 등 전통적 공학 문제에 적합

  • 수학적 계획법 사용 시:

  • 복잡한 수학적 제약 조건이 존재하는 경우

  • 수렴 보장이 중요한 경우

  • 다목적, 비선형, 고차원 문제에 일반적으로 적용 가능

  • 하이브리드 접근:

  • 최적화 기준법으로 좋은 초기 해 생성

  • 이후 수학적 계획법으로 세밀한 최적화 수행

  • 효율성과 정확성의 균형을 추구하는 전략

태그: 최적화 기준법 수학적 계획법 경사 하강법 SQP 내부 점법

7월 3일 16:44에 게시됨