MATLAB中的优化入门教程

228 阅读6分钟

MATLAB中的优化入门

优化是指在满足某些特定约束和条件的前提下,通过组合输入来实现最佳输出。它涉及到使用给定的标准在给定的数据中选择最好的,或组合输入以获得最佳工作状态。

它是一门数学学科,致力于获得最大值和最小值。因此,优化是线性编程的一部分。

优化问题通常是最大化或最小化一个实际函数。他们通过从一个允许的集合中系统地选择输入值并计算出函数的值来实现这一目标。

前提条件

要学习这篇文章,你需要具备以下条件。

  • 安装了[MATLAB]。
  • 对[MATLAB]基础知识的正确理解。

简介

各种各样的优化问题出现在所有定量学科中,如计算机科学、工程和经济学。因此,它是日常生活中的一个重要工具,每天有数十亿人感受到它的影响。

本文将探讨优化的基础知识以及如何在Matlab中应用它们。我们还将看看它在各个领域的应用。

一个优化问题是由df(x)/dx=0 。寻找曲线中的最小点可以用while循环来完成。

例如,给定一个函数y(x)= 2x^2+20x-22 ,你可以用while循环找到它的最小点,如下图所示。

clear
clc
x = -20: 0.1: 20;                  %x values
y = 2.*x.^2 + 20.*x - 22;          % the function
plot(x,y)                          %plotting the output

grid

在这里,我们使用plot 函数绘制方程,如上所示。然后用while循环遍历曲线上的所有数据点。当前值大于前一个值的那一点被确定为曲线的最小值。

完成后,使用fprintf 函数打印输出。这个打印出来的输出就是我们函数的最小点。

i = 1;                    %initializing i to 1.
while (y(i) > y(i + 1))    % when the initial i is greater than i+1
    i = i + 1;             % The new value of i
end

x (i);                        % x position of i
y(i)                          % y position of i
fprintf('the minimum of the curve is %d and %d\n', x(i), y(i))

plotted function

Obtained results

while 循环方法被用于简单的数学函数中。对于复杂的方程,我们使用Matlab的内置函数。在Matlab中用于优化的内建函数如下。

  • fminbnd() - 是用于寻找固定区间上的单变量函数的最小值。单变量函数是指只有一个变量的函数。
  • fminsearch()- 这个函数类似于fminbnd() ,只是它处理的是多于一个变量的函数。

让我们在前面while 循环方法中使用的数学方程中应用fminbnd 函数。要获得更多关于内置函数的信息,请在命令窗口中输入help fminbnd

Matlab会在命令窗口中显示关于它的详细信息。但是,首先创建一个脚本,在其中定义你的函数。

注意,函数的名字和脚本的名字应该是一样的。

function f = mysimplefunc(x)

f = 2.*x.^2 + 20.*x - 22;

在本例中,mysimplefunc 是脚本中定义的函数的名称。这意味着我们脚本的名称应该是mysimplefunc.mf 是函数变量。在这个脚本中,你定义了你是如何找到最小点的。

现在创建另一个脚本来定义这个变量,并在这里调用mysimplefunc 函数。这个脚本的代码应该是这样的。

x = -20:0.1:20;       % The x values

f = mysimplefunc(x);   % The values of f mysimplefunc.m function we created.

plot(x,f)

上面的代码绘制了这个函数;用f 的值作为Y轴。使用fminbnd 函数来获得最小点。

xmin = fminbnd(@mysimplefunc, -20, 20);

ymin = mysimplefunc(xmin);

当使用fmibnd 函数时,分别给它输入,@mysimplefuncx-axis 的最小值和最大值的范围。

在获得x轴上的最小点后,Matlab通过参考x 的最小值来获得最小y

我们要求Matlab使用disp 函数来显示结果。

disp(xmin)
disp(ymin)

Matlab得到的结果与使用while 循环方法时得到的结果相似。所以,我们在寻找其最小点的方程对两种方法来说又是相似的。

例2

现在让我们引入一个更复杂的方程并找出它的最低点。

在这个例子中,f(x)=x^3-4x 是这个函数。第一步是画出这个函数,然后找到它的最低点。

现在,使用fminbnd 函数来看看它在这些复杂方程中的应用。

创建一个脚本函数mysimplefunc.m 来定义数学方程。

脚本函数的代码如下所示。

function f = mysimplefunc(x)

f = x.^3 - 4*x;

创建另一个脚本并调用mysimplefunc 函数;在这个新脚本中包含我们的数学方程。

绘制数学方程并获得其最小点,如下所示。

x = -3:0.1:3;

f = mysimplefunc(x);

plot(x,f)

xmin = fminbnd(@mysimplefunc, -3, 3);

ymin = mysimplefunc(xmin);

disp(xmin)
disp(ymin)

运行该代码后,结果应如下。

plot of the function

minimum point

罗森布罗克的香蕉函数

这是一个函数,是优化软件的一个著名测试案例。

给定一个函数f(x,y) = (1-x)^2 + 100(y-x^2)^2 (Rosenbrock的香蕉函数),我们首先绘制这个函数,然后找到其最小点。在这种情况下,我们的函数中有两个变量,即:xy

你不能使用之前的fminbnd 函数,而是要使用fminsearch 函数来获得。

请注意,fminbnd 函数只能处理一个变量,而fminsearch 可以接受一个以上的变量。第一步总是绘制你的函数。对于Rosenbrock's banana function ,绘制它的冲浪图和网格图。

clear
clc

[x,y] = meshgrid(-2:0.1:2, -1:0.1:3);

f = (1-x).^2 + 100.*(y-x.^2).^2;  % our defined function

figure(1)
surf(x,y,f) %use surf function to plot the surf of the function

figure(2)
mesh(x,y,f)   %use mesh function to plot the surf of the function

figure(3)
surf(x,y,f)    %use surf function to plot the surf of the function, but in this case, color the plotting
shading interp;
colormap (hot);     %used to color the plot

plot of the banana function

使用fminsearch 函数来寻找给定数学函数的最小值。

完成后,创建一个函数脚本来定义该函数。

function f = bananafunc(x)

f = (1-x(1)).^2 + 100.*(x(2)-x(1).^2).^2;

在前面的例子中,xy 是变量,但在这种情况下我们用向量代替。这就是为什么我们用x 的第一个值代替x ,也就是x(1) ,用x(2) 代替y

现在在命令窗口中执行fminsearch ,找到这个点。代码将如下图所示。

[x, fval] = fminsearch(@bananafunc, [-1.2; 1])  %fval is the f function values.

注意,在命令窗口中执行上述命令之前,先运行你的函数脚本。

minimum point of banana function

在我们的结果中,x 有两个值。第一个值是x ,第二个值是yfvalz

结论

优化是科学和工程领域的一个重要工具。它适用于广泛的领域,如基于模型的设计、机器学习和数据分析。

Matlab是一种优秀的优化语言。正如我们在上面看到的,内置的函数使得进行这种优化变得非常容易。

此外,代码也很容易理解和使用。这使得它成为解决这个问题的合适工具。

<!-- MathJax script -->
<script type="text/javascript" async
    src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
    MathJax.Hub.Config({
    tex2jax: {
      inlineMath: [['$','$'], ['\\(','\\)']],
      displayMath: [['$$','$$']],
      processEscapes: true,
      processEnvironments: true,
      skipTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
      TeX: { equationNumbers: { autoNumber: "AMS" },
           extensions: ["AMSmath.js", "AMSsymbols.js"] }
    }
    });
    MathJax.Hub.Queue(function() {
      // Fix <code> tags after MathJax finishes running. This is a
      // hack to overcome a shortcoming of Markdown. Discussion at
      // https://github.com/mojombo/jekyll/issues/199
      var all = MathJax.Hub.getAllJax(), i;
      for(i = 0; i < all.length; i += 1) {
          all[i].SourceElement().parentNode.className += ' has-jax';
      }
    });
    MathJax.Hub.Config({
    // Autonumbering by mathjax
    TeX: { equationNumbers: { autoNumber: "AMS" } }
    });
  </script>