优化_优化算法 - CSDN
精华内容
参与话题
  • Matlab数学建模(五):优化模型之标准模型

    千次阅读 多人点赞 2018-11-18 20:34:38
    (1)了解最优化模型。 (2)掌握线性规划的优化求解。 (3)掌握整数规划的优化求解。 (4)了解Matlab的图形化应用。 二、实例演练  1、谈谈你对最优化模型的了解。  最优化模型是数学建模大赛中最常见的...

    一、学习目标

    (1)了解最优化模型。

    (2)掌握线性规划的优化求解。

    (3)掌握整数规划的优化求解。

    (4)了解Matlab的图形化应用。

    二、实例演练

         1、谈谈你对最优化模型的了解。

            最优化模型是数学建模大赛中最常见的问题类型之一。一般说来,凡是寻求最大、最小、最远、最近、最经济、最丰富、最高效、最耗时的目标,都可以划入优化问题的范畴。MATLAB 优化工具箱和全局优化工具箱对多个优化问题提供了完整的解决方案,前者涵盖了线性规划、混合整型线性规划、二次规划、非线性优化、非线性最小二乘的求解器,后者囊括了全局搜索、多初始点、模式搜索、遗传算法等求解算法。

           最优化即在一定的条件下,寻求使目标最小(大)的设计参数或决策。在优化问题中有两个关键对象:目标函数约束条件。哈哈哈,这让笔者想起来高中学到的线性规划,其实,本节谈到的最优化模型跟高中的线性规划还真有点像。不过,高中的线性规划问题约束条件很少,一般是通过作图法来求解。本节的最优化模型约束条件一般比高中的线性规划多很多,并且我们要通过写代码去求解,而不是作图。常规优化问题,其数学表达可以描述为:

    其中x 为长度n的决策变量向量,f(x) 为目标函数,G(x) 为约束函数。

    以上数学表达式看不明白也没关系,因为下面我们会通过两个具体的例子去讲解分析。

    求解目标函数的最小(大)值,一个高效而精确的解决方案不仅取决于约束条件和变量数量,更取决于目标函数和约束函数的特性。明确优化类型是确认优化方案的前提,让我们看一下这些特性如何划分:

    常见的目标函数有:

    线性规划:被广泛的应用于变量之间可线性表示的财务、能源、运营研究等现代管理领域中。

    混合整数线性规划:扩展了线性规划问题,增加了最优解中部分或全部变量必须是整数的约束。例如,如果一个变量代表要认购的股票数量,则只应取整数值。同样,如果一个变量代表发电机的开/关状态,则只应取二进制值(0 或 1)。

    二次规划:目标函数或约束函数为多元二次函数。此优化应用于财务金融中投资组合优化、发电厂发电优化、工程中设计优化等领域。

    最小二乘:分为线性和非线性,通过最小化误差的平方和寻找变量的最优函数匹配。非线性最小二乘优化还可用于曲线拟合。

     

    对 MATLAB 提供的各类优化问题的算法,我们称之为求解器(Solver)。根据其求解目标,被分为四大组:

    • 极小值优化组:找到目标函数出发点 x0 附近的局部极小值

    • 多目标优化组:找到最小化一组函数的最大值或指定的值

    • 方程求解组:找到非线性方程 f(x) = 0 出发点 x0 附近的解

    • 最小二乘法(曲线拟合)组:最小化平方和

    仅优化工具箱就提供了近 20 种求解器,面对如此繁多的选项,用户往往一头雾水。幸好,MATLAB 提供了简单明了的参考工具 —— 优化决策表。可谓一表在手,优化不愁:

    上表中*表示算法由全局工具箱提供。

    我的天呀,你是不是已经被上面的内容吓傻了。看不太懂?没关系。我们现在只需知道有那么一回事即可,不必苦恼。等遇到相应的问题时我们再去结合具体的例子去深入学习和理解。

        2、已知目标函数和约束条件如下,试求解目标函数的最小值。

                                 

           初一看,HPS、PP、EP、P1、I1,……等等,这些是什么东东?别紧张,它们只是变量,把它们当成x,y,z这种常见的变量去看待即可。我数了一下,约束函数中共有19条数学表达式,涉及16个变量。是挺难搞的,用高中的作图法怕是解决不了。别怕,我们有Matlab,通过代码去搞定它。

           好,现在我们开始一步步去求解它。

    a. 首先,根据题目确认这是一个线性规划问题。而线性规划的通用数学表达式和MATLAB标准形式为:

    这个标准形式很重要,上面的A,b,Aeq,beq,lb,ub我们后面要用到。

    b. 对于线性规划的优化求解步骤(也适用于其他优化方案),建议如下:

        1 ) 选择优化求解器

        2 ) 将所有变量合并为一个向量

        3 ) 创建边界约束(lb,ub)

        4 ) 创建线性不等式约束(A,b)

        5 ) 创建线性等式约束(Aeq,beq)

        6 ) 创建目标函数

        7 ) 优化问题求解

        8 ) 结果检验

    上面的求解步骤非常重要,我们的代码整体框架跟求解步骤差不多。

    现在我们按照上面的求解步骤去求解:

    (1)选择优化求解器。

    这道题目是这是一个线性规划问题。求解线性规划问题,我们一般选用linprog。linprog在写代码将要写完才需用到。在第一步我们只需要知道一个线性规划问题,代码按照求解线性规划问题去写即可。

    (2)将所有变量合并为一个向量。

    目标函数和约束条件中共有HPS、PP、EP、P1、I1等16个变量,我们需要将其合并为一个向量。除了合并为一个向量外,我们还将每个变量依次分别赋值1,2,3,4,……16。

    %% 将所有变量合并为一个向量,共16个变量
    variables = {'I1','I2','HE1','HE2','LE1','LE2','C','BF1','BF2','HPS','MPS','LPS','P1','P2','PP','EP'}
    N = length(variables)
    for v = 1:N
        eval([variables{v},'=',num2str(v),';'])
    end

    (3)创建边界约束(lb,ub)

    lb是指low boundary,即最低边界。ub是指up boundary,即最高边界。在这一步中,我们需要把约束条件里的不等式(该不等式只含单个变量,如2500<=P1<=6250,3000<=P2<=9000)找出来,并根据它们的上下边界写代码。

    %% 设置上下限约束(lb<=x<=ub)
    % 设置下限约束,即lb<=x
    lb = zeros(size(variables)); % 1x16的矩阵,每个数都是0
    lb([P1,P2,MPS,LPS]) = [2500,3000,271536,100623];
    % 设置上限约束,即x<=ub
    ub = Inf(size(variables)); % 1想6的矩阵,每个数都是无穷大
    ub([P1,P2,I1,I2,C,LE2])= [6250,9000,192000,244000,62000,142000];

    (4)创建线性不等式约束(A,b)。

    在这一步需要将约束条件里的不等式(该不等式含两个或两个以上变量)找出来,并根据它们的上下边界写代码。

    %% 创建线性不等式约束(A*x<=b)
    A = zeros(3,16); % 3x16的矩阵,每个数均为0,为什么是3x16,因为约束条件有3个不等式
    % 由不等式I1-HE1<=132000得到下面一行代码
    A(1,I1)=1; A(1,HE1)=-1; b(1) = 132000;
    % 由不等式-EP-PP<=12000得到下面一行代码
    A(2,EP)=-1; A(2,PP)=-1; b(2) = -12000;
    % 由不等式-P1-P2-PP<=-24550得到下面一行代码
    A(3,[P1,P2,PP])=[-1,-1,-1];b(3)=-24550;

    (5)创建线性等式约束(Aeq,beq)。

    在这一步需要把约束条件中的等式找出来,并通过移项,让等式的右边为0。

    %% 创建线性等式约束(Aeq*x=beq)
    Aeq=zeros(8,16);beq=zeros(8,1) % 约束条件中共有8个等式
    % 把等式I2=LE2+HE2转化为LE2+HE2-I2=0后,得到下面一行代码
    Aeq(1,[LE2,HE2,I2])=[1,1,-1];
    Aeq(2,[LE1,LE2,BF2,LPS])=[1,1,1,-1];
    Aeq(3,[I1,I2,BF1,HPS])=[1,1,1,-1];
    Aeq(4,[C,MPS,LPS,HPS])=[1,1,1,-1];
    Aeq(5,[LE1,HE1,C,I1])=[1,1,1,-1];
    Aeq(6,[HE1,HE2,BF1,BF2,MPS])=[1,1,1,-1,-1];
    Aeq(7,[HE1,LE1,C,P1,I1])=[1267.8,1251.4,192,3413,-1359.8];
    Aeq(8,[HE2,LE2,P2,I2])=[1267.8,1251.4,3413,-1359.8];

    (6)创建目标函数。

    %% 创建目标函数
    f = zeros(size(variables));
    % 由目标函数0.002614HPS+0.0239PP+0.009825EP
    f([HPS,PP,EP]) = [0.002614,0.0239,0.009825];

    (7) 求解问题

    %% 由linprog实现线性规划问题求解
    options = optimoptions('linprog','Algorithm','dual-simplex');
    % 将前面已经确定的各个参数传入linprog()中
    [x, fval] = linprog(f,A,b,Aeq,beq,lb,ub,options);
    for d=1:N
        fprintf('%12.2f\t%s\n',x(d),variables{d})
    end

    fprintf函数是将求解后每个变量的打印出来。

    求解结果如下:

    下面把完整的源代码贴上:

    clc,clear,close all
    %% 选择优化求解器,线性规划求解可由linprog实现
    
    %% 将所有变量合并为一个向量,共16个变量
    variables = {'I1','I2','HE1','HE2','LE1','LE2','C','BF1','BF2','HPS','MPS','LPS','P1','P2','PP','EP'}
    N = length(variables)
    for v = 1:N
        eval([variables{v},'=',num2str(v),';'])
    end
    
    %% 设置上下限约束(lb<=x<=ub)
    % 设置下限约束,即lb<=x
    lb = zeros(size(variables)); % 1x16的矩阵,每个数都是0
    lb([P1,P2,MPS,LPS]) = [2500,3000,271536,100623];
    % 设置上限约束,即x<=ub
    ub = Inf(size(variables)); % 1想6的矩阵,每个数都是无穷大
    ub([P1,P2,I1,I2,C,LE2])= [6250,9000,192000,244000,62000,142000];
    
    %% 创建线性不等式约束(A*x<=b)
    A = zeros(3,16); % 3x16的矩阵,每个数均为0,为什么是3x16,因为约束条件有3个不等式
    % 由不等式I1-HE1<=132000得到下面一行代码
    A(1,I1)=1; A(1,HE1)=-1; b(1) = 132000;
    % 由不等式-EP-PP<=12000得到下面一行代码
    A(2,EP)=-1; A(2,PP)=-1; b(2) = -12000;
    % 由不等式-P1-P2-PP<=-24550得到下面一行代码
    A(3,[P1,P2,PP])=[-1,-1,-1];b(3)=-24550;
    
    %% 创建线性等式约束(Aeq*x=beq)
    Aeq=zeros(8,16);beq=zeros(8,1) % 约束条件中共有8个等式
    % 把等式I2=LE2+HE2转化为LE2+HE2-I2=0后,得到下面一行代码
    Aeq(1,[LE2,HE2,I2])=[1,1,-1];
    Aeq(2,[LE1,LE2,BF2,LPS])=[1,1,1,-1];
    Aeq(3,[I1,I2,BF1,HPS])=[1,1,1,-1];
    Aeq(4,[C,MPS,LPS,HPS])=[1,1,1,-1];
    Aeq(5,[LE1,HE1,C,I1])=[1,1,1,-1];
    Aeq(6,[HE1,HE2,BF1,BF2,MPS])=[1,1,1,-1,-1];
    Aeq(7,[HE1,LE1,C,P1,I1])=[1267.8,1251.4,192,3413,-1359.8];
    Aeq(8,[HE2,LE2,P2,I2])=[1267.8,1251.4,3413,-1359.8];
    
    %% 创建目标函数
    f = zeros(size(variables));
    % 由目标函数0.002614HPS+0.0239PP+0.009825EP
    f([HPS,PP,EP]) = [0.002614,0.0239,0.009825];
    
    %% 由linprog实现线性规划问题求解
    options = optimoptions('linprog','Algorithm','dual-simplex');
    % 将前面已经确定的各个参数传入linprog()中
    [x, fval] = linprog(f,A,b,Aeq,beq,lb,ub,options);
    for d=1:N
        fprintf('%12.2f\t%s\n',x(d),variables{d})
    end

      3、下面是一个整数规划问题,已知目标函数和约束条件如下,求解目标函数的最大值。

                                          

         求解最大值问题和求解最小值问题本质上是一致的,求解最大值也可以转换为求解最小值。

    例如:本题要求解z=3*x1-2*x2+5*x3的最大值,也就是要求解y=-3*x1+2*x2-5*x3的最小值。求解线性规划最小值问题我们在上面已经学过。本题还有一个比较特殊的问题是,约束条件中的三个变量均为整数,而且是0或1,这也是所谓的0-1规划问题。

    求解整值问题要用到专门的求解器 intlinprog。

    clc,clear,close all
    % 求z=3*x1 - 2*x2 + 5*x3的最大值转化为求y=-3*x1 + 2*x2 - 5*x3的最小值。
    f = [-3;2;-5]; % 创建目标函数
    intcon=[1,2,3];
    A=[1 2 -1; 1 4 1; 1 1 0; 0 4 1]; % 四个不等式中的变量系数
    b=[2;4;3;6]; % 约束条件中不等式右边的常数
    lb=[0,0,0]; % x1,x2,x3=0
    ub=[1,1,1]; % x1,x2,x3=1
    Aeq=[0,0,0];
    beq=0;
    x=intlinprog(f,intcon,A,b,Aeq,beq,lb,ub)

    我想提一下intcon=[1,2,3]这句代码是怎么回事。

    下面我举一个简单的例子来说明intcon的用法。

    X=[x1,x2,x3,x4,x5,x6],其中x2, x3, x6只能取整数
    intcon = [2,3,6]
    如果所有变量都只能取整数,则:intcon = [1,2,3,4,5,6]; 比较方便的写法是:intcon = 1:6
    如果只有x4取整数,则:intcon = 4;就是约束整形变量

    在本题中,除了x1,x2,x3=0或1外,没有其它的等式了。故Aeq=[0,0,0];beq=0;

     4、图形化应用

    在数学建模竞赛中,我们一般通过代码来进行求解问题,图形化应用可以用来检验结果是否正确。

    MATLAB 在数据分析领域如此受欢迎,除了其提供丰富的内置算法集,还有各类友好的应用界面。在优化工具箱中,也有这么一个强大的工具—— Optimization App,可以在 MATLAB Apps 窗口或者运行 optmitool 命令打开。它是一个交互式的图形化应用工具,无需手写代码,直接在图形界面中设置各类求解器、配置目标函数、约束条件,即可运行优化算法并使中间结果和最终结果可视化。

    在 Optimization App 中,只需点击菜单栏中的 File > Generate Code,即可将 App 中的各项设置自动生成 MATLAB 代码,用户可实现算法的复用和二次开发。

    展开全文
  • 程序员的数学:优化理论

    千人学习 2020-03-11 14:43:07
    程序员的数学-优化理论
  • 优化理论与凸优化到底是干嘛的?

    万次阅读 多人点赞 2017-12-17 10:46:35
    优化的定义 1.1 凸优化 ...1.1 凸优化优化问题目前在机器学习,数据挖掘等领域应用非常广泛,因为机器学习简单来说,主要做的就是优化问题,先初始化一下权重参数,然后利用优化方法来优化这个
    1. 凸优化的定义
      1.1 凸优化
      1.2 全局最优化与局部最优化
    2. Least-squares and linear programming(最小二乘与线性规划)
      2.1 最小二乘
      2.2 线性规划
    3. 最优化方法的一般结构
    4. 优化理论在机器学习,深度学习中扮演的角色

    1.优化的定义

    1.1 凸优化

    最优化问题目前在机器学习,数据挖掘等领域应用非常广泛,因为机器学习简单来说,主要做的就是优化问题,先初始化一下权重参数,然后利用优化方法来优化这个权重,直到准确率不再是上升,迭代停止,那到底什么是最优化问题呢?

    它的一般形式为:

    minimize f0(x)
    使 fi(x)bi,i=1,,m
    第一个为优化的目标,即最小化目标函数f(x),而带大于号或小于号的,则是约束条件。我们希望找到一个满足约束条件的x,使得对于任意的z满足约束条件:
    f1(z)b1,,fm(z)bm
    f0(z)f0(x)
    x就是我们所求的最后结果。

    • 相当于你要从上海去北京,你可以选择搭飞机,或者火车,动车,但只给你500块钱,要求你以最快的时间到达,其中到达的时间就是优化的目标,500块钱是限制条件,选择动车,火车,或者什么火车都是x。

    满足所有约束条件的点集称为可行域,记为X,又可以写为:

    min f(x)   s.t xX
    ,s.t表示受限于(subject to)。

    在优化问题中,应用最广泛的是凸优化问题:

    • 若可行域X是一个凸集:即对于任给的x,yX,总有
      λx+(1λ)yX, λ(0,1)
    • 并且目标函数是一个凸函数:即
      f(λx+(1λ)y))λf(x)+(1λ)f(y)
      我们称这样的优化问题为凸优化问题。

    用图像来表示就是:
    这里写图片描述
    函数上方的点集就是凸集,函数上任意两点的连线,仍然在函数图像上方。

    一句话说清楚就是:希望找到合适的x,使得f0(x)最小。

    1.2 全局最优化与局部最优化

    全局最优化指的是在满足条件约束的情况下,找到唯一的一个点满足最大值或者最小值。

    局部最优化指的是在满足条件约束的情况下,有可能找到一个局部最大/小点,但不是全局最大或者最小的点。
    用图像表示为:
    这里写图片描述

    2.Least-squares and linear programming(最小二乘与线性规划)

    关于这两个问题的更详细的例子会在接下来的文章中说到,这次只是简单的介绍一下我们的内容。

    2.1 最小二乘

    最小二乘问题是无约束的优化问题,通常可以理解为测量值与真实值之间的误差平方和:

    minimize f0(x)=Axb22=i=1k(aTixbi)2
    其中ARk x nk>naTiAix

    这个问题既然没有约束条件,那应该怎么求解呢?我们的目标是求解出最好的x,观察这个式子可以发现,这个式子一定是大于等于0的,所以这样的最优化问题,我们可以把它转成线性方程来求解:

    ATAx=ATb
    AT为A的转置,因此根据矩阵的逆:
    (ATA)1ATA=1
    可以把上式表示为:
    x=(ATA)1ATb

    加权的最小二乘问题

    i=1kwi(aTixbi)2
    权值均为正数,代表每一个aTixbi对结果的影响程度。

    正则化的最小二乘问题:

    i=1k(aTixbi)2+ρi=1nx2i
    ρ是人为的选择的,用来权衡 最小化ki=1(aTixbi)2的同时,使得ni=1x2i不必太大的关系。

    2.2 线性规划
    另一类重要的优化问题是线性规划,它的目标函数和约束条件都是线性的:

    minimize cTx
    s.t    aTixbi,i=1,,m

    用画图的方法,就是根据条件,画出可行域,然后将目标函数在可行域上移动,直到得到最大值。
    这里写图片描述

    3.最优化方法的一般结构

    最优化的过程,相当于爬山,如图:
    这里写图片描述
    希望找到一个点列xk使得他的函数值是一直减少的,直到到达某一停止条件或者达到最小值的点xk.

    用数学上的术语可以表示为:

    • xk为第k次迭代点,dk为第k次搜索方向,αk为第k次迭代的步长因子,则第k次迭代为:
      xk+1=xk+αkdk

    从这里可以看到不同的步长和不同的搜索方向组成了不同的优化方法,这就是最优化理论中所讨论的。fxk的函数,搜索方向dkfxk处的下降方向,即dk满足:

    f(xk)Tdk<0
    或者
    f(xk+1)=f(xk+αkdk)<f(xk)

    而最优化的基本可以表示为:给定初始点xk

    1. 确定搜索方向dk,即按照一定规则画方法确定f在xk处的下降方向
    2. 确定步长因子αk,使得目标函数有一定的下降
    3. xk+1=xk+αkdk
      不断迭代,直到xk+1满足某种某种停止条件,即得到最优解xk+1

    最优化中的问题中,大部分都是在寻找各种各样的方法确定步长和方向,使得迭代的速度尽可能快,得到的解尽可能是最优的解。

    4.优化理论在机器学习,深度学习中扮演的角色

    凸优化,或者更广泛的说,是最优化理论,在目前的机器学习,数据挖掘,或者是深度学习的神经网络中,都要用到。

    他的地位相当于人的脊背一样的,支撑着整个模型的学习过程。因为模型,通俗来说就像人学习思考一样,我们自己知道自己该学什么,该怎么学,发现自己的知识学错了之后怎么调整,但计算机可没有人这么聪明,知道学什么,往哪里学。

    而最优化,就是告诉模型应该学什么,怎么学的工具。模型学习的往往都是一个映射函数,也就是模型中的参数W,这个参数的好坏,得看答案才能知道,但知道自己错了之后,该往哪里学,怎么学,怎么调整,这就是优化理论在其中扮演的角色。如果没有优化理论,那么模型是不知道该怎么学习的,也就是没有了最优化,模型的学习永远都是停滞不前的,这下你知道最优化理论的重要性了吧。

    展开全文
  • 优化理论与方法

    千次阅读 2019-04-23 12:28:47
    优化问题 :eg:,其中x在控制问题中被称为为控制决策变量;在数学优化中叫做决策量。无论是最优控制还是数学优化(数学规划)都是优化问题,即都是这样的形式。 1. 优化的两个基本问题 确定一个优化的必要或/和...

    优化问题 :eg:{min}_xf\left ( x \right ) st. x\in D,其中x在控制问题中被称为为控制决策变量;在数学优化中叫做决策量。无论是最优控制还是数学优化(数学规划)都是优化问题,即都是{min}_xf\left ( x \right ) st. x\in D这样的形式。

    1. 优化的两个基本问题

    • 确定一个优化的必要或/和充分的条件(建模)。
    • 设计一个数值程序(算法的设计+程序的实现)。

    遗传算法在弱优化或无约束优化问题中应用较好。

    2. 优化的相关概念

    静态    vs    动态    数学优化\leftrightarrow最优控制;

    连续    vs   离散    数学优化的离散与连续问题\leftrightarrow控制问题的连续与离散问题;

    凸   vs   非凸   既可能与目标有关,又可能与约束有关;

    完美   vs   满意   结果的完美解与满意解;

    严格   vs   启发   方法在数学上是否严格收敛到最优与否。

    2.1 静态优化(参数优化、数学规划等方法)

    • 对变量进行优化;
    • 约束条件与目标为代数方程或不等式。

    2.2 动态优化(变分问题、最优控制)

    • 对函数进行优化(例如最优决策路径)(函数未知)
    • 目标为积分型泛函;
    • 约束条件包含微分方程。

    2.3 连续优化与离散优化

    • 可行域(决策空间)
    •     0-1规划
    •     整数规划
    • 时间序列
    •     离散时间的动态规划——差分描述
    •     连续时间的动态规划——微分描述

    2.4 确定性优化与随机优化

    • DP 动态优化 确定性;
    • MDP Markov决策过程 随机性

    2.5 凸与非凸

    • 凸集;
    • 凸函数

    2.6 启发与随机化搜索

    • 启发式+随机化=高级启发或超级启发(遗传算法、模拟退火算法、蚁群算法);

    2.7 完美解与满意解

    • 一般需要对满意解进行评价

    3 优化方法

    迭代    vs   解析    计算机喜爱迭代方法,并且这种方法效率高;

    串行    vs    并行    

    求导    vs    搜索

    点对点    vs    集到集

    解析    vs    启发

    注:结构知识绝对重要,搜索方法应当在结构信息的指导下进行搜索。启发、学习、人的才智以及软优化在求解方法中占有重要地位。

    一些常用的迭代方法

    • 梯度法(利用了梯度结构信息)
    • 牛顿法(利用了梯度+Hessen矩阵等结构信息)
    • BFGS (共轭梯度结构信息)
    展开全文
  • 常见的web性能优化方法

    万次阅读 多人点赞 2017-06-07 15:47:49
    前端优化是复杂的,针对方方面面的资源都有不同的方式。那么,前端优化的目的是什么 ?  1. 从用户角度而言,优化能够让页面加载得更快、对用户的操作响应得更及时,能够给用户提供更为友好的体验。  2. 从服务商...

    前言:关于优化问题,随着项目经验不断累积,多方查找资料进行拼接合并,形成如下文章,之后遇到类似好的方法,会不断补充完善。

    前端是庞大的,包括 HTML、 CSS、 Javascript、Image 、Flash等等各种各样的资源。前端优化是复杂的,针对方方面面的资源都有不同的方式。那么,前端优化的目的是什么 ?

    1. 从用户角度而言,优化能够让页面加载得更快、对用户的操作响应得更及时,能够给用户提供更为友好的体验。
    2. 从服务商角度而言,优化能够减少页面请求数、或者减小请求所占带宽,能够节省可观的资源。
    总之,恰当的优化不仅能够改善站点的用户体验并且能够节省相当的资源利用。

    大概有如下优化方法:



      具体参考:http://www.cnblogs.com/developersupport/p/webpage-performance-best-practices.html
      一、页面级优化
      1. 减少 HTTP请求数
      这条策略基本上所有前端人都知道,而且也是最重要最有效的。都说要减少 HTTP请求,那请求多了到底会怎么样呢 ?首先,每个请求都是有成本的,既包含时间成本也包含资源成本。一个完整的请求都需要经过 DNS寻址、与服务器建立连接、发送数据、等待服务器响应、接收数据这样一个 “漫长” 而复杂的过程。时间成本就是用户需要看到或者 “感受” 到这个资源是必须要等待这个过程结束的,资源上由于每个请求都需要携带数据,因此每个请求都需要占用带宽。另外,由于浏览器进行并发请求的请求数是有上限的 (具体参见此处 ),因此请求数多了以后,浏览器需要分批进行请求,因此会增加用户的等待时间,会给用户造成站点速度慢这样一个印象,即使可能用户能看到的第一屏的资源都已经请求完了,但是浏览器的进度条会一直存在。
      减少 HTTP请求数的主要途径包括:
      (1). 从设计实现层面简化页面
      如果你的页面像百度首页一样简单,那么接下来的规则基本上都用不着了。保持页面简洁、减少资源的使用时最直接的。如果不是这样,你的页面需要华丽的皮肤,则继续阅读下面的内容。
      (2). 合理设置 HTTP缓存
      缓存的力量是强大的,恰当的缓存设置可以大大的减少 HTTP请求。以有啊首页为例,当浏览器没有缓存的时候访问一共会发出 78个请求,共 600多 K数据 (如图 1.1),而当第二次访问即浏览器已缓存之后访问则仅有 10个请求,共 20多 K数据 (如图 1.2)。 (这里需要说明的是,如果直接 F5刷新页面的话效果是不一样的,这种情况下请求数还是一样,不过被缓存资源的请求服务器是 304响应,只有 Header没有Body ,可以节省带宽 )
      怎样才算合理设置 ?原则很简单,能缓存越多越好,能缓存越久越好。例如,很少变化的图片资源可以直接通过 HTTP Header中的Expires设置一个很长的过期头 ;变化不频繁而又可能会变的资源可以使用 Last-Modifed来做请求验证。尽可能的让资源能够在缓存中待得更久。关于 HTTP缓存的具体设置和原理此处就不再详述了,有兴趣的可以参考下列文章:
    HTTP1.1协议中关于缓存策略的描述
    Fiddler HTTP Performance中关于缓存的介绍
      (3). 资源合并与压缩
      如果可以的话,尽可能的将外部的脚本、样式进行合并,多个合为一个。另外, CSS、 Javascript、Image 都可以用相应的工具进行压缩,压缩后往往能省下不少空间。
      (4). CSS Sprites
      合并 CSS图片,减少请求数的又一个好办法。
      (5). Inline Images

      使用 data: URL scheme的方式将图片嵌入到页面或 CSS中,如果不考虑资源管理上的问题的话,不失为一个好办法。如果是嵌入页面的话换来的是增大了页面的体积,而且无法利用浏览器缓存。使用在 CSS中的图片则更为理想一些。

    .sample-inline-png {
        padding-left: 20px;
        background: white url('data:image/png;base64,iVBORw0KGgoAA
    AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0l
    EQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6
    P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC') no-repeat scroll left top;
    }
      (6). Lazy Load Images(自己对这一块的内容还是不了解)
      这条策略实际上并不一定能减少 HTTP请求数,但是却能在某些条件下或者页面刚加载时减少 HTTP请求数。对于图片而言,在页面刚加载的时候可以只加载第一屏,当用户继续往后滚屏的时候才加载后续的图片。这样一来,假如用户只对第一屏的内容感兴趣时,那剩余的图片请求就都节省了。 有啊首页 曾经的做法是在加载的时候把第一屏之后的图片地址缓存在 Textarea标签中,待用户往下滚屏的时候才 “惰性” 加载。

      2. 将外部脚本置底(将脚本内容在页面信息内容加载后再加载)
      前文有谈到,浏览器是可以并发请求的,这一特点使得其能够更快的加载资源,然而外链脚本在加载时却会阻塞其他资源,例如在脚本加载完成之前,它后面的图片、样式以及其他脚本都处于阻塞状态,直到脚本加载完成后才会开始加载。如果将脚本放在比较靠前的位置,则会影响整个页面的加载速度从而影响用户体验。解决这一问题的方法有很多,在 这里有比较详细的介绍 (这里是译文和 更详细的例子 ),而最简单可依赖的方法就是将脚本尽可能的往后挪,减少对并发下载的影响。
      3. 异步执行 inline脚本(其实原理和上面是一样,保证脚本在页面内容后面加载。)
      inline脚本对性能的影响与外部脚本相比,是有过之而无不及。首页,与外部脚本一样, inline脚本在执行的时候一样会阻塞并发请求,除此之外,由于浏览器在页面处理方面是单线程的,当 inline脚本在页面渲染之前执行时,页面的渲染工作则会被推迟。简而言之, inline脚本在执行的时候,页面处于空白状态。鉴于以上两点原因,建议将执行时间较长的 inline脚本异步执行,异步的方式有很多种,例如使用 script元素的defer 属性(存在兼容性问题和其他一些问题,例如不能使用 document.write)、使用setTimeout ,此外,在HTML5中引入了 Web Workers的机制,恰恰可以解决此类问题。

      4. Lazy Load Javascript(只有在需要加载的时候加载,在一般情况下并不加载信息内容。)

      随着 Javascript框架的流行,越来越多的站点也使用起了框架。不过,一个框架往往包括了很多的功能实现,这些功能并不是每一个页面都需要的,如果下载了不需要的脚本则算得上是一种资源浪费 -既浪费了带宽又浪费了执行花费的时间。目前的做法大概有两种,一种是为那些流量特别大的页面专门定制一个专用的 mini版框架,另一种则是 Lazy Load。YUI 则使用了第二种方式,在 YUI的实现中,最初只加载核心模块,其他模块可以等到需要使用的时候才加载。


      5. 将 CSS放在 HEAD中
      如果将 CSS放在其他地方比如 BODY中,则浏览器有可能还未下载和解析到 CSS就已经开始渲染页面了,这就导致页面由无 CSS状态跳转到 CSS状态,用户体验比较糟糕。除此之外,有些浏览器会在 CSS下载完成后才开始渲染页面,如果 CSS放在靠下的位置则会导致浏览器将渲染时间推迟。
      6. 异步请求 Callback(就是将一些行为样式提取出来,慢慢的加载信息的内容)
      在某些页面中可能存在这样一种需求,需要使用 script标签来异步的请求数据。类似:
      Javascript:

    function myCallback(info){ 
    //do something here 

      HTML:

      cb返回的内容 :
    myCallback('Hello world!');
    像以上这种方式直接在页面上写 <script>对页面的性能也是有影响的,即增加了页面首次加载的负担,推迟了 DOMLoaded和window.onload 事件的触发时机。如果时效性允许的话,可以考虑在 DOMLoaded事件触发的时候加载,或者使用 setTimeout方式来灵活的控制加载的时机。
      7. 减少不必要的 HTTP跳转
      对于以目录形式访问的 HTTP链接,很多人都会忽略链接最后是否带 ’/',假如你的服务器对此是区别对待的话,那么你也需要注意,这其中很可能隐藏了 301跳转,增加了多余请求。具体参见下图,其中第一个链接是以无 ’/'结尾的方式访问的,于是服务器有了一次跳转。
      8. 避免重复的资源请求
      这种情况主要是由于疏忽或页面由多个模块拼接而成,然后每个模块中请求了同样的资源时,会导致资源的重复请求

            9 精简Javascript和CSS

    精简就是将Javascript或CSS中的空格和注释全去掉,

    复制代码
    复制代码
    body {
        line-height: 1;
    }
    ol, ul {
        list-style: none;
    }
    blockquote, q {
        quotes: none;
    }
    复制代码
    复制代码

    精简后版本

    复制代码
    body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}
    复制代码

    统计表明精简后的文件大小平均减少了21%,即使在应用Gzip的文件也会减少5%。

    用来帮助我们做精简的工具很多,主要可以参考如下,

    JS compressors:

    CSS compressors:

    与VS集成比较好的工具如下.


      二、代码级优化
      1. Javascript
      (1). DOM
      DOM操作应该是脚本中最耗性能的一类操作,例如增加、修改、删除 DOM元素或者对 DOM集合进行操作。如果脚本中包含了大量的 DOM操作则需要注意以下几点:
      a. HTML Collection(HTML收集器,返回的是一个数组内容信息)
      在脚本中 document.images、document.forms 、getElementsByTagName()返回的都是 HTMLCollection类型的集合,在平时使用的时候大多将它作为数组来使用,因为它有 length属性,也可以使用索引访问每一个元素。不过在访问性能上则比数组要差很多,原因是这个集合并不是一个静态的结果,它表示的仅仅是一个特定的查询,每次访问该集合时都会重新执行这个查询从而更新查询结果。所谓的 “访问集合” 包括读取集合的 length属性、访问集合中的元素。
      因此,当你需要遍历 HTML Collection的时候,尽量将它转为数组后再访问,以提高性能。即使不转换为数组,也请尽可能少的访问它,例如在遍历的时候可以将 length属性、成员保存到局部变量后再使用局部变量。
      b. Reflow & Repaint
      除了上面一点之外, DOM操作还需要考虑浏览器的 Reflow和Repaint ,因为这些都是需要消耗资源的,具体的可以参加以下文章:
    如何减少浏览器的repaint和reflow?
    Understanding Internet Explorer Rendering Behaviour
    Notes on HTML Reflow

      (2). 慎用 with
    with(obj){ p = 1}; 代码块的行为实际上是修改了代码块中的 执行环境 ,将obj放在了其作用域链的最前端,在 with代码块中访问非局部变量是都是先从 obj上开始查找,如果没有再依次按作用域链向上查找,因此使用 with相当于增加了作用域链长度。而每次查找作用域链都是要消耗时间的,过长的作用域链会导致查找性能下降。
      因此,除非你能肯定在 with代码中只访问 obj中的属性,否则慎用 with,替代的可以使用局部变量缓存需要访问的属性。
      (3). 避免使用 eval和 Function
      每次 eval 或 Function 构造函数作用于字符串表示的源代码时,脚本引擎都需要将源代码转换成可执行代码。这是很消耗资源的操作 —— 通常比简单的函数调用慢 100倍以上。
      eval 函数效率特别低,由于事先无法知晓传给 eval 的字符串中的内容,eval在其上下文中解释要处理的代码,也就是说编译器无法优化上下文,因此只能有浏览器在运行时解释代码。这对性能影响很大。
      Function 构造函数比 eval略好,因为使用此代码不会影响周围代码 ;但其速度仍很慢。
      此外,使用 eval和 Function也不利于Javascript 压缩工具执行压缩。
      (4). 减少作用域链查找(这方面设计到一些内容的相关问题)
      前文谈到了作用域链查找问题,这一点在循环中是尤其需要注意的问题。如果在循环中需要访问非本作用域下的变量时请在遍历之前用局部变量缓存该变量,并在遍历结束后再重写那个变量,这一点对全局变量尤其重要,因为全局变量处于作用域链的最顶端,访问时的查找次数是最多的。
      低效率的写法:
    // 全局变量 
    var globalVar = 1; 
    function myCallback(info){ 
    for( var i = 100000; i--;){ 
    //每次访问 globalVar 都需要查找到作用域链最顶端,本例中需要访问 100000 次 
    globalVar += i; 
    }

      更高效的写法:
    // 全局变量 
    var globalVar = 1; 
    function myCallback(info){ 
    //局部变量缓存全局变量 
    var localVar = globalVar; 
    for( var i = 100000; i--;){ 
    //访问局部变量是最快的 
    localVar += i; 

    //本例中只需要访问 2次全局变量
    在函数中只需要将 globalVar中内容的值赋给localVar 中区
    globalVar = localVar; 
    }
      此外,要减少作用域链查找还应该减少闭包的使用。
      (5). 数据访问
      Javascript中的数据访问包括直接量 (字符串、正则表达式 )、变量、对象属性以及数组,其中对直接量和局部变量的访问是最快的,对对象属性以及数组的访问需要更大的开销。当出现以下情况时,建议将数据放入局部变量:
      a. 对任何对象属性的访问超过 1次
      b. 对任何数组成员的访问次数超过 1次
      另外,还应当尽可能的减少对对象以及数组深度查找。
      (6). 字符串拼接
      在 Javascript中使用"+" 号来拼接字符串效率是比较低的,因为每次运行都会开辟新的内存并生成新的字符串变量,然后将拼接结果赋值给新变量。与之相比更为高效的做法是使用数组的 join方法,即将需要拼接的字符串放在数组中最后调用其 join方法得到结果。不过由于使用数组也有一定的开销,因此当需要拼接的字符串较多的时候可以考虑用此方法。

      关于 Javascript优化的更详细介绍请参考:
    Write Efficient Javascript(PPT)
    Efficient JavaScript
      2. CSS选择符
      在大多数人的观念中,都觉得浏览器对 CSS选择符的解析式从左往右进行的,例如
    #toc A { color: #444; }
      这样一个选择符,如果是从右往左解析则效率会很高,因为第一个 ID选择基本上就把查找的范围限定了,但实际上浏览器对选择符的解析是从右往左进行的。如上面的选择符,浏览器必须遍历查找每一个 A标签的祖先节点,效率并不像之前想象的那样高。根据浏览器的这一行为特点,在写选择符的时候需要注意很多事项,有人已经一一列举了, 详情参考此处。

      3. HTML
      对 HTML本身的优化现如今也越来越多的受人关注了,详情可以参见这篇 总结性文章 。

      4. Image压缩
      图片压缩是个技术活,不过现如今这方面的工具也非常多,压缩之后往往能带来不错的效果,具体的压缩原理以及方法在《 Even Faster Web Sites》第10 章有很详细的介绍,有兴趣的可以去看看。
      总结
      本文从页面级以及代码级两个粒度对前端优化的各种方式做了一个总结,这些方法基本上都是前端开发人员在开发的过程中可以借鉴和实践的,除此之外,完整的前端优化还应该包括很多其他的途径,例如 CDN、 Gzip、多域名、无 Cookie服务器等等,由于对于开发人员的可操作性并不强大,在此也就不多叙述了,详细的可以参考 Yahoo和Google 的这些“金科玉律。
    展开全文
  • 优化方法答案(部分)

    万次阅读 多人点赞 2019-03-04 10:08:35
    学霸的资料,偷偷拿来与大家共勉…希望有帮助 ^^ 第一章 第二章 第三章 第四章
  • 前端优化方案

    千次阅读 2019-06-11 18:10:10
    1 优化css 1.1 避免使用CSS表达式 用CSS表达式动态设置CSS属性,是一种强大又危险的方式。从IE5开始支持,但从IE8起就不推荐使用了。例如,可以用CSS表达式把背景颜色设置成按小时交替的 尽量减少标签选择器的使用...
  • sql优化的几种方式

    万次阅读 多人点赞 2019-11-11 09:15:50
    一、为什么要对SQL进行优化 我们开发项目上线初期,由于业务数据量相对较少,一些SQL的执行效率对程序运行效率的影响不太明显,而开发和运维人员也无法判断SQL对程序的运行效率有多大,故很少针对SQL进行专门的优化...
  • 三种快排,四种优化

    千次阅读 2018-08-31 16:18:07
    1、快速排序的基本思想: 快速排序使用分治的思想,通过一趟排序将待排序列分割成两部分,其中一部分记录的关键字均比另一部分记录的关键字小。之后分别对这两部分记录继续进行排序,以达到整个序列有序的目的。...
  • 优化方法总结:SGD,Momentum,AdaGrad,RMSProp,Adam

    万次阅读 多人点赞 2018-11-21 13:32:30
    1. SGDBatch Gradient Descent在每一轮的训练过程中,Batch Gradient Descent算法用整个训练集的数据计算cost fuction的梯度,并用该梯度对模型参数进行更新:Θ=Θ−α⋅▽ΘJ(Θ)\Theta = \Theta -\alpha \cdot \...
  • 深度学习各种优化函数详解

    万次阅读 2017-04-13 15:02:51
    深度学习中有众多有效的优化函数,比如应用最广泛的SGD,Adam等等,而它们有什么区别,各有什么特征呢?下面就来详细解读一下一、先来看看有哪些优化函数BGD 批量梯度下降所谓的梯度下降方法是无约束条件中最常用的...
  • intelliJ IDEA 自动优化导入包

    万次阅读 2019-01-23 14:04:58
    Intellij IDEA使用教程相关系列 目录 步骤:Settings→Editor→General→Auto Import,如图所示 选中Optimize imports on the fly和Add unambiguous imports on the fly 勾选Optimize imports on the fly ...
  • 超直白win7性能优化方案

    万次阅读 2017-08-30 10:41:43
    超直白win7性能优化方案
  • 数值优化(Numerical Optimization)学习系列-目录

    万次阅读 多人点赞 2015-12-27 19:07:11
    数值优化对于最优化问题提供了一种迭代算法思路,通过迭代逐渐接近最优解,分别对无约束最优化问题和带约束最优化问题进行求解。 该系列教程可以参考的资料有 1. 《Numerical Optimization 2nd》–Jorge Nocedal ...
  • C++ 手动开O2优化

    万次阅读 多人点赞 2017-09-02 19:45:47
    O2优化能使程序的编译效率大大提升 从而减少程序的运行时间,达到优化的效果。 C++程序中的O2开关如下所示: #pragma GCC optimize(2) 只需将这句话放到程序的开头即可打开O2优化开关。
  • O1优化会消耗少多的编译时间,它主要对代码的分支,常量以及表达式等进行优化。  O2会尝试更多的寄存器级的优化以及指令级的优化,它会在编译期间占用更多的内存和编译时间。  O3在O2的基础上进行更多的优化,...
  • 有时候,在VS调试中,会出现下面的报错: 导致无法进行正常调试的现象。这是因为我们设置了代码优化,在项目/XXX属性中,把代码优化关闭即可 过早优化是万恶之源 ...
  • 优化理论视频网站

    万次阅读 2018-01-24 13:57:18
    找了好久的最优化理论视频,主要是针对凸优化的,视频列表如下 上交大最优化-youku:http://list.youku.com/albumlist/show?id=6461357&ascending=1&page=1 上交大最优化-bilibili:...
  • 优化问题(OPT,convex optimization problem)指定义在凸集中的凸函数最优化的问题。一般形式为: 凸优化问题 虽然凸优化的条件比较苛刻,但仍然在机器学习参数最优化领域有广泛的应用。凸优化问题的优势...
  • matlab版本需要ga/pso优化代码的可以私信q,本人可以指导,亲自测试有效,都可以跑出来 部分截图如下: 研究了一小段时间,终于研究出来了,对于模型处理数据挺好的,有比较优化。...
1 2 3 4 5 ... 20
收藏数 2,412,390
精华内容 964,956
关键字:

优化