В этом примере показано, как ускорить минимизацию дорогой задачи оптимизации с помощью функций в Optimization Toolbox™ и Global Optimization Toolbox. В первой части примера мы решаем задачу оптимизации путем выполнения функций последовательным способом, и второй частью примера мы решаем ту же задачу с помощью параллельного цикла for (parfor
) функция путем выполнения функций параллельно. Мы сравниваем время, потраченное оптимизационной функцией в обоих случаях.
В целях этого примера мы решаем задачу в четырех переменных, где цель и ограничительные функции сделаны искусственно дорогими путем приостановки.
function f = expensive_objfun(x) %EXPENSIVE_OBJFUN An expensive objective function used in optimparfor example. % Copyright 2007-2013 The MathWorks, Inc. % Simulate an expensive function by pausing pause(0.1) % Evaluate objective function f = exp(x(1)) * (4*x(3)^2 + 2*x(4)^2 + 4*x(1)*x(2) + 2*x(2) + 1);
function [c,ceq] = expensive_confun(x) %EXPENSIVE_CONFUN An expensive constraint function used in optimparfor example. % Copyright 2007-2013 The MathWorks, Inc. % Simulate an expensive function by pausing pause(0.1); % Evaluate constraints c = [1.5 + x(1)*x(2)*x(3) - x(1) - x(2) - x(4); -x(1)*x(2) + x(4) - 10]; % No nonlinear equality constraints: ceq = [];
fmincon
Мы интересуемся измерением времени, потраченного fmincon
в сериале так, чтобы мы могли сравнить его с параллельным временем.
startPoint = [-1 1 1 -1]; options = optimoptions('fmincon','Display','iter','Algorithm','interior-point'); startTime = tic; xsol = fmincon(@expensive_objfun,startPoint,[],[],[],[],[],[],@expensive_confun,options); time_fmincon_sequential = toc(startTime); fprintf('Serial FMINCON optimization takes %g seconds.\n',time_fmincon_sequential);
First-order Norm of Iter F-count f(x) Feasibility optimality step 0 5 1.839397e+00 1.500e+00 3.211e+00 1 11 -9.760099e-01 3.708e+00 7.902e-01 2.362e+00 2 16 -1.480976e+00 0.000e+00 8.344e-01 1.069e+00 3 21 -2.601599e+00 0.000e+00 8.390e-01 1.218e+00 4 29 -2.823630e+00 0.000e+00 2.598e+00 1.118e+00 5 34 -3.905339e+00 0.000e+00 1.210e+00 7.302e-01 6 39 -6.212992e+00 3.934e-01 7.372e-01 2.405e+00 7 44 -5.948762e+00 0.000e+00 1.784e+00 1.905e+00 8 49 -6.940062e+00 1.233e-02 7.668e-01 7.553e-01 9 54 -6.973887e+00 0.000e+00 2.549e-01 3.920e-01 10 59 -7.142993e+00 0.000e+00 1.903e-01 4.735e-01 11 64 -7.155325e+00 0.000e+00 1.365e-01 2.626e-01 12 69 -7.179122e+00 0.000e+00 6.336e-02 9.115e-02 13 74 -7.180116e+00 0.000e+00 1.069e-03 4.670e-02 14 79 -7.180409e+00 0.000e+00 7.799e-04 2.815e-03 15 84 -7.180410e+00 0.000e+00 6.189e-06 3.122e-04 Local 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. Serial FMINCON optimization takes 17.0722 seconds.
Начиная с ga
обычно берет намного больше вычислений функции, чем fmincon
, мы удаляем дорогое ограничение из этой проблемы и выполняем оптимизацию без ограничений вместо этого. Передайте пустые матрицы []
для ограничений. Кроме того, мы ограничиваем максимальное количество поколений к 15 для ga
так, чтобы ga
может завершить работу за разумное количество времени. Мы интересуемся измерением времени, потраченного ga
так, чтобы мы могли сравнить его с параллельным ga
оценка. Обратите внимание на то, что выполнение ga
требует Global Optimization Toolbox.
rng default % for reproducibility try gaAvailable = false; nvar = 4; gaoptions = optimoptions('ga','MaxGenerations',15,'Display','iter'); startTime = tic; gasol = ga(@expensive_objfun,nvar,[],[],[],[],[],[],[],gaoptions); time_ga_sequential = toc(startTime); fprintf('Serial GA optimization takes %g seconds.\n',time_ga_sequential); gaAvailable = true; catch ME warning(message('optimdemos:optimparfor:gaNotFound')); end
Best Mean Stall Generation Func-count f(x) f(x) Generations 1 100 -5.546e+05 1.483e+15 0 2 150 -5.581e+17 -1.116e+16 0 3 200 -7.556e+17 6.679e+22 0 4 250 -7.556e+17 -7.195e+16 1 5 300 -9.381e+27 -1.876e+26 0 6 350 -9.673e+27 -7.497e+26 0 7 400 -4.511e+36 -9.403e+34 0 8 450 -5.111e+36 -3.011e+35 0 9 500 -7.671e+36 9.346e+37 0 10 550 -1.52e+43 -3.113e+41 0 11 600 -2.273e+45 -4.67e+43 0 12 650 -2.589e+47 -6.281e+45 0 13 700 -2.589e+47 -1.015e+46 1 14 750 -8.149e+47 -5.855e+46 0 15 800 -9.503e+47 -1.29e+47 0 Optimization terminated: maximum number of generations exceeded. Serial GA optimization takes 80.2351 seconds.
Конечное дифференцирование, используемое функциями в Optimization Toolbox к аппроксимативным производным, сделано в параллели с помощью parfor
покажите, если Parallel Computing Toolbox доступен и существует параллельный пул рабочих. Точно так же ga
, gamultiobj
, и patternsearch
решатели в Global Optimization Toolbox выполняют функции параллельно. Использовать parfor
покажите, мы используем parpool
функционируйте, чтобы настроить параллельную среду. Компьютер, на котором публикуется этот пример, имеет четыре ядра, таким образом, parpool
запускает четырех рабочих MATLAB®. Если уже существует параллельный пул, когда вы запускаете этот пример, мы используем тот пул; см. документацию для parpool
для получения дополнительной информации.
if max(size(gcp)) == 0 % parallel pool needed parpool % create the parallel pool end
fmincon
Минимизировать нашу дорогую задачу оптимизации с помощью параллельного fmincon
функция, мы должны явным образом указать, что наша цель и ограничительные функции могут быть оценены параллельно и что мы хотим fmincon
использовать его параллельную функциональность по мере возможности. В настоящее время конечное дифференцирование может быть сделано параллельно. Мы интересуемся измерением времени, потраченного fmincon
так, чтобы мы могли сравнить его с последовательным fmincon
запущенный.
options = optimoptions(options,'UseParallel',true); startTime = tic; xsol = fmincon(@expensive_objfun,startPoint,[],[],[],[],[],[],@expensive_confun,options); time_fmincon_parallel = toc(startTime); fprintf('Parallel FMINCON optimization takes %g seconds.\n',time_fmincon_parallel);
First-order Norm of Iter F-count f(x) Feasibility optimality step 0 5 1.839397e+00 1.500e+00 3.211e+00 1 11 -9.760099e-01 3.708e+00 7.902e-01 2.362e+00 2 16 -1.480976e+00 0.000e+00 8.344e-01 1.069e+00 3 21 -2.601599e+00 0.000e+00 8.390e-01 1.218e+00 4 29 -2.823630e+00 0.000e+00 2.598e+00 1.118e+00 5 34 -3.905339e+00 0.000e+00 1.210e+00 7.302e-01 6 39 -6.212992e+00 3.934e-01 7.372e-01 2.405e+00 7 44 -5.948762e+00 0.000e+00 1.784e+00 1.905e+00 8 49 -6.940062e+00 1.233e-02 7.668e-01 7.553e-01 9 54 -6.973887e+00 0.000e+00 2.549e-01 3.920e-01 10 59 -7.142993e+00 0.000e+00 1.903e-01 4.735e-01 11 64 -7.155325e+00 0.000e+00 1.365e-01 2.626e-01 12 69 -7.179122e+00 0.000e+00 6.336e-02 9.115e-02 13 74 -7.180116e+00 0.000e+00 1.069e-03 4.670e-02 14 79 -7.180409e+00 0.000e+00 7.799e-04 2.815e-03 15 84 -7.180410e+00 0.000e+00 6.189e-06 3.122e-04 Local 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. Parallel FMINCON optimization takes 8.11945 seconds.
Минимизировать нашу дорогую задачу оптимизации с помощью ga
функция, мы должны явным образом указать, что наша целевая функция может быть выполнена параллельно и что мы хотим ga
использовать его параллельную функциональность по мере возможности. Использовать параллельный ga
мы также требуем, чтобы 'Векторизованная' опция была установлена в значение по умолчанию (т.е. 'off'). Мы снова интересуемся измерением времени, потраченного ga
так, чтобы мы могли сравнить его с последовательным ga
запущенный. Хотя этот запуск может отличаться от последовательного потому что ga
использует генератор случайных чисел, количество дорогих вычислений функции является тем же самым в обоих запусках. Обратите внимание на то, что выполнение ga
требует Global Optimization Toolbox.
rng default % to get the same evaluations as the previous run if gaAvailable gaoptions = optimoptions(gaoptions,'UseParallel',true); startTime = tic; gasol = ga(@expensive_objfun,nvar,[],[],[],[],[],[],[],gaoptions); time_ga_parallel = toc(startTime); fprintf('Parallel GA optimization takes %g seconds.\n',time_ga_parallel); end
Best Mean Stall Generation Func-count f(x) f(x) Generations 1 100 -5.546e+05 1.483e+15 0 2 150 -5.581e+17 -1.116e+16 0 3 200 -7.556e+17 6.679e+22 0 4 250 -7.556e+17 -7.195e+16 1 5 300 -9.381e+27 -1.876e+26 0 6 350 -9.673e+27 -7.497e+26 0 7 400 -4.511e+36 -9.403e+34 0 8 450 -5.111e+36 -3.011e+35 0 9 500 -7.671e+36 9.346e+37 0 10 550 -1.52e+43 -3.113e+41 0 11 600 -2.273e+45 -4.67e+43 0 12 650 -2.589e+47 -6.281e+45 0 13 700 -2.589e+47 -1.015e+46 1 14 750 -8.149e+47 -5.855e+46 0 15 800 -9.503e+47 -1.29e+47 0 Optimization terminated: maximum number of generations exceeded. Parallel GA optimization takes 15.6984 seconds.
X = [time_fmincon_sequential time_fmincon_parallel]; Y = [time_ga_sequential time_ga_parallel]; t = [0 1]; plot(t,X,'r--',t,Y,'k-') ylabel('Time in seconds') legend('fmincon','ga') ax = gca; ax.XTick = [0 1]; ax.XTickLabel = {'Serial' 'Parallel'}; axis([0 1 0 ceil(max([X Y]))]) title('Serial Vs. Parallel Times')
Использование параллельного вычисления функции через parfor
повышенный эффективность обоих fmincon
и ga
. Улучшение обычно лучше для дорогой цели и ограничительных функций.