精华内容
下载资源
问答
  • 粒子群算法(PSO)解决函数优化问题

    万次阅读 2019-03-22 22:27:00
    粒子群算法(PSO)解决函数优化问题 本文转载自:http://wenku.baidu.com/link?url=E6F5Nv6kW5nOQ2BD3mm4q5ld22o_pLQ48jPD-9N4q_1Sh-lJOrWVCo1Bc9SYB514goOOpXQJrk5sqTyzvrVthvnhXWqBnwzAMl4S8Miveka### 目录 ...

    粒子群算法(PSO)解决函数优化问题


    本文转载自:http://wenku.baidu.com/link?url=E6F5Nv6kW5nOQ2BD3mm4q5ld22o_pLQ48jPD-9N4q_1Sh-lJOrWVCo1Bc9SYB514goOOpXQJrk5sqTyzvrVthvnhXWqBnwzAMl4S8Miveka###


     

    目录

    粒子群算法(PSO)解决函数优化问题

     

    引言

    一、 问题描述

    1.1 连续函数求最大值问题

    二、算法设计

    2.1算法流程框图

    2.2 算法实现

    2.3 参数选择

    三、程序设计

    四、 结果与分析

    4.1 实验结果

    4.2 分析

    五、总结


    引言

        本文主要利用粒子群算法解决连续函数的最小值问题,粒子群优化是一种新兴的基于群体智能的启发式全局搜索算法,粒子群优化算法通过粒子间的竞争和协作以实现在复杂搜索空间中寻找全局最优点。它具有易理解、易实现、全局搜索能力强等特点,倍受科学与工程领域的广泛关注,已经成为发展最快的智能优化算法之一。本文介绍了粒子群优化算法的基本原理,分析了其特点,并将其应用于函数优化问题求解。

        求函数最优值问题,对此问题,传统的优化技术很容易陷入局部最优解,求得全局优化解的概率不高,可靠性低;为此,建立尽可能大概率的求解全局优化解算法是求解函数优化的一个重要问题。本文采用粒子群算法来解决这类问题。

    一、 问题描述

    1.1 连续函数求最大值问题

        本文主要选取一个三维函数,利用matlab编写粒子群算法程序来求解,以验证遗传算法在解决函数优化问题中的有效性。本文选取的函数为:f=x(1).^2+x(2).^2+x(3).^2,求它的最小值。

    1.2 粒子群算法

        PSO从这种模型中得到启示并用于解决优化问题。PSO 中,每个优化问题的潜在解都是搜索空间中的一只鸟,称之为粒子。所有的粒子都有一个由被优化的函数决定的适值( fitness value) ,每个粒子还有一个速度决定它们飞翔的方向和距离。然后粒子们就追随当前的最优粒子在解空间中搜索。

        PSO初始化为一群随机粒子(随机解),然后通过迭代找到最优解。在每一次迭代中,粒子通过跟踪两个极值来更新自己;第一个就是粒子本身所找到的最优解,这个解称为个体极值;另一个极值是整个种群目前找到的最优解,这个极值是全局极值。另外也可以不用整个种群而只是用其中一部分作为粒子的邻居,那么在所有邻居中的极值就是局部极值。

        假设在一个 维的目标搜索空间中,有 个粒子组成一个群落,其中第 个粒子表示为一个 维的向量

     , 。

    第 个粒子的“飞行 ”速度也是一个 维的向量,记为

     , 。

    第 个粒子迄今为止搜索到的最优位置称为个体极值,记为

     , 。

    整个粒子群迄今为止搜索到的最优位置为全局极值,记为

     

    在找到这两个最优值时,粒子根据如下的公式(1.1)和( 1.2)来更新自己的速度和位置:

                (1.1)

                            (1. 2)

    其中: 和 为学习因子,也称加速常数(acceleration constant), 和 为[0,1]范围内的均匀随机数。式(1.1)右边由三部分组成,第一部分为“惯性(inertia)”或“动量(momentum)”部分,反映了粒子的运动“习惯(habit)”,代表粒子有维持自己先前速度的趋势;第二部分为“认知(cognition)”部分,反映了粒子对自身历史经验的记忆(memory)或回忆(remembrance),代表粒子有向自身历史最佳位置逼近的趋势;第三部分为“社会(social)”部分,反映了粒子间协同合作与知识共享的群体历史经验。      

    二、算法设计

         这部分内容主要是针对本文主要研究问题的类型确定粒子群算法具体实现过程和一些参数的选择。

    2.1算法流程框图

                          图1 粒子群算法流程图

    2.2 算法实现

    算法的流程如下:

    ① 初始化粒子群,包括群体规模 ,每个粒子的位置 和速度 

    ② 计算每个粒子的适应度值 ;

    ③ 对每个粒子,用它的适应度值 和个体极值 比较,如果  ,则用 替换掉 ;

    ④ 对每个粒子,用它的适应度值 和全局极值 比较,如果 则用 替 ;

    ⑤ 根据公式(1.1),(1.2)更新粒子的速度 和位置  ;

    ⑥ 如果满足结束条件(误差足够好或到达最大循环次数)退出,否则返回②。

    2.3 参数选择

            本算法中主要的参数变量为 (惯性权值),  , (加速因子),N (种群数),M (迭代次数),D (粒子维数)。

    (1)种群规模

    通常,种群太小则不能提供足够的采样点,以致算法性能很差;种群太大尽管可以增加优化信息,阻止早熟收敛的发生,但无疑会增加计算量,造成收敛时间太长,表现为收敛速度缓慢。种群规模一般设为100~1000。本文选择种群规模为100。

    (2)最大迭代次数

    迭代次数越多能保证解的收敛性,但是影响运算速度,本文选1000次。

    (3)惯性权值

    惯性权重 表示在多大程度上保留原来的速度。 较大,全局收敛能力强,局部收敛能力弱; 较小,局部收敛能力强,全局收敛能力弱。本文选0.6。

    (4)加速因子

    加速常数 和 分别用于控制粒子指向自身或邻域最佳位置的运动。文献[20]建议 ,并通常取 。本文也取 。

    (5)粒子维数

        本文中粒子维数取决于待优化函数的维数,例如本文取3。

        需要说明的是,本文的程序允许改变这些参数,因为本文编写的程序参照matlab工具箱,留给用户解决这类问题一个接口函数,上述的各个参数正是接口函数的参数,因此允许改变。另外对于 和c也可采用变参数法,即随迭代次数增加,利用经验公式使它们动态调整,本文采用固定值。

    三、程序设计

        程序主要由两个m文件组成,pso.m是遗传算法接口文件,fitness.m是待求解的问题函数,只需要修改fitness.m里的目标函数就可实现不同问题的解。

    (1)pso.m文件

    function [xm,fv] = PSO(fitness,N,c1,c2,w,M,D)

    %fitness-是要优化的目标函数,N-种群数,c1,c2-学习因子,w-惯性权重,M-迭代次数,D-粒子维数。

    format long;

    %初始化种群

    for i=1:N

        for j=1:D

            x(i,j)=randn;  %随机初始化位子

            v(i,j)=randn;  %随机初始化速度

        end

    end

    %先计算各个粒子的适应度,并初始化pi-粒子个体极值和pg-全局极值

    for i=1:N

       p(i)=fitness(x(i,:));

       y(i,:)=x(i,:);

    end

    pg = x(N,:);             %pg为全局极值

    for i=1:(N-1)

        if fitness(x(i,:))<fitness(pg)

            pg=x(i,:);

        end

    end

    %进入粒子群算法主要循环

    for t=1:M

        for i=1:N

            v(i,:)=w*v(i,:)+c1*rand*(y(i,:)-x(i,:))+c2*rand*(pg-x(i,:));

            x(i,:)=x(i,:)+v(i,:);

            if fitness(x(i,:))<p(i)

                p(i)=fitness(x(i,:));

                y(i,:)=x(i,:);

            end

            if p(i)<fitness(pg)

                pg=y(i,:);

            end

        end

     Pbest(t)=fitness(pg);

    end

    xm = pg';

    fv = fitness(pg);

    (2)目标函数fitness.m文件

    function f=fitness(x)

    f=x(1).^2+x(2).^2+x(3).^2 ;

    end

    需要说明的是,针对不同的函数优化,只需要改变目标函数就可以。

    (3)在命令行输入或建立调用m文件

         在命令行先后输入[xm,fv] = PSO(@fitness,100,2,2,0.6,1000,3),或建立包涵该语句的m文件,运行即可得到结果。

    四、 结果与分析

    4.1 实验结果

    (1)对于目标函数f=x(1).^2+x(2).^2+x(3).^2 优化结果如下:

       xm =1.0e-162 *

       0.556163077454623

       0.937292023592359

       0.146573921409127

    fv =0 , fv是最优值,xm为最优值对应的自变量值。

    4.2 分析

        通过对实验结果和已知最小值比较可知,该算法能有效解决这类问题,需要特别指出的是xm的取值只是近似值,另外,本文的粒子群算法程序只是实现粒子群算法的基本功能,该算法还有待进一步改进。

    五、总结

        本文利用粒子群算法思想,通过编写matlab程序,对一个三维连续函数进行优化得到了较好的仿真结果,证明粒子群算法在解决这类问题的可行性。另外,在编写本文的工作过程中,提高了自己对粒子群算法的理解和应用能力。为今后利用智能算法撰写论文或进行科学研究打下了很好地基础。

     

    展开全文
  • 特别是,在实际应用中如果我们能把一个问题转化为凸优化问题,是非常好的一步。而能够这样做的前提,是知道基本的函数的凸性以及有哪些保凸运算。上镜图有助于我们从集合的角度理解这个函数为什么是凸的(集合的保凸...

    这一节主要学习凸函数的定义以及性质。了解保凸运算,以及上镜图与下水平集等。这些基础知识看似零乱,然而却是后面的基础。特别是,在实际应用中如果我们能把一个问题转化为凸优化问题,是非常好的一步。而能够这样做的前提,是知道基本的函数的凸性以及有哪些保凸运算。上镜图有助于我们从集合的角度理解这个函数为什么是凸的(集合的保凸运算);水平集是以函数的形式表示集合,类似于等高线,在历史上是重要的方法。这里我们通过下水平集把函数的凸性和集合的凸性联系了起来。

    基本性质

    定义

    凸函数(Convex)的定义如下:

    这里写图片描述

    即:自变量的凸组合的函数值小于等于函数值的凸组合。

    严格凸函数,只要把等号去掉。

    凹函数(Concave)是凸函数取负号。

    仿射函数是既凸且凹的

    常见的凸函数

    • 仿射函数
    • eaXaReaX,∀a∈R
    • 指数函数:xαR++R++,对α1α≥1或者α0α≤0

    扩展值延伸

    定义凸函数在定义域外的值为,从而将定义域延伸至全空间RnRn

    一阶条件(First Order Conditions)

    函数f可微分,则函数f是凸函数的充要条件是其定义域dom f是凸集且对于任意的x,ydom fx,y∈dom f,下式成立

    f(y)f(x)+f(x)T(yx)f(y)≥f(x)+∇f(x)T(y−x)

    即大于等于一阶泰勒近似。上式说明了一个凸函数的局部信息。对于严格凸和凹函数,有相应的结论。

    对于一个凸函数,其一阶泰勒近似是原函数的一个全局下估计。反之,若某个函数的一阶泰勒近似总是其全局下估计,则这个函数是凸的。

    二阶条件

    函数f二阶可微(函数在定义域的开集上处处存在二阶导数),则f是凸函数的充要条件是:其Hessian矩阵是半正定矩阵。即对于所有xdom fx∈dom f,有

    2f(x)0∇2f(x)⪰0

    此条件说明函数的倒数是非递减的。从几何上看是指函数图像在x点具有正的曲率。

    函数f二阶可微(函数在定义域的开集上处处存在二阶导数),则f是凹函数的充要条件是:其Hessian矩阵是半负定矩阵。即对于所有xdom fx∈dom f,有

    2f(x)0∇2f(x)⪯0

    R上的例子

    • 指数函数。对任意aRa∈R, 函数eaxeax在R上是凸的
    • 幂函数。当a1a≥1或者a0a≤0时,xaxaR++R++上是凸函数;当0a10≤a≤1时,xaxaR++R++上是凹函数
    • 绝对值幂函数。当p1p≥1时,函数|x|p|x|pRR上是凸函数。
    • 对数函数。函数log(x)log⁡(x)R++R++上是凹函数。
    • 负熵。函数xlog(x)xlog⁡(x)是定义域上的凸函数。

     RnRn上的一些例子

    • 范数。RnRn上任意范数为凸函数。

    • 最大值函数。函数f(x)=max{x1,...,xn}f(x)=max{x1,...,xn}RnRn上是凸的。

    • 二次-线性分式函数。函数f(x,y)=x2/yf(x,y)=x2/y,其定义域为dom f=R×R++={(x,y)R2|y>0}dom f=R×R++={(x,y)∈R2|y>0}是凸函数。

    这里写图片描述

    • 指数和的对数。函数f(x)=log(ex1+...+exn)f(x)=log⁡(ex1+...+exn)RnRn上是凸函数。

    • 几何平均。几何平均函数f(x)=(ni=1xi)1/nf(x)=(∏i=1nxi)1/n在定义域Rn++R++n上是凹函数。

    • 对数-行列式。函数f(X)=logdetXf(X)=log⁡detX在定义域Sn++S++n是凹函数。

    判断函数的凸性的方法:

    • 根据二阶条件,求出Hessian矩阵,根据Hessian矩阵是否半正定。或者直接判断
    • 根据一阶条件判断
    • 把函数转化为与其定义域相交的直线,通过单变量函数判断原函数的凸性。
    • 把函数看成由其他简单的凸函数通过保凸运算导出。

    下水平集(Sublevel Set)

    水平集是一种通过函数表示集合的方法。函数的αα−下水平集的定义是:

    这里写图片描述

    即:使得函数值小于等于αα的自变量的集合。

    同理可以得到函数的αα−上水平集的定义。

    凸函数的任意下水平集都是凸集。

    凹函数的任意上水平集都是凸集。

    因此,可以根据函数的凸性来判断集合的凸性。

    比如:

    这里写图片描述

    这里算术平均是凸函数,几何平均是凹函数。其复合函数是凹的,因此集合是凸集。

    上镜图(Epigraph)

    函数的图像是指:

    这里写图片描述

    函数的上镜图是指函数图像上面的部分:

    这里写图片描述

    显然,可以通过函数图像的上镜图判断函数的凸性。

    一个函数是凸函数,当且仅当上镜图是凸集。

    一个函数是凹函数,当且仅当亚图是凸集。这里写图片描述

    一阶条件的几何解释

    考虑一阶条件,根据上镜图的定义可得,

    这里写图片描述

    这里写图片描述

    Jessen不等式及其扩展

    一阶条件的基本不等式也叫做Jessen不等式,可以扩展到无穷项和、积分以及期望。

    保凸运算

    学习保持凸性或者凹性的运算,可以用于构造新的凸函数或者凹函数,以及判断一个函数的凸性。

    非负加权求和

    显然,如果函数f是凸函数,则其非负加权求和仍然是凸函数。

    f=w1f1+...+wmfmf=w1f1+...+wmfm

    对凹函数有相应的结论。

    从上镜图可以得到这个结论,前面我们已经知道凸集通过线性变换之后的像依然是凸集。而

    这里写图片描述

    复合仿射映射

    这里写图片描述

    这个性质和集合的保凸运算类似。

    逐点最大和逐点上确界

    如果f1,...,fmf1,...,fm是凸的,那么f(x)=max{f1,...,fm}f(x)=max{f1,...,fm}也是凸的。

    逐点最大的性质可以扩展至无限个凸函数的逐点上确界。如果对于任意yAy∈A,函数f(x,y)f(x,y)关于xx都是凸的,则函数g

    g(x)=supyAf(x,y)g(x)=supy∈Af(x,y)

    关于x也是凸的。

    从上镜图的角度理解,一系列函数的逐点上确界函数对应着这些函数上镜图的交集,而我们知道凸集的交集仍然是凸集,所以一系列函数的逐点上确界函数的上镜图是凸集。

    集合的支撑函数

    这里写图片描述

    到集合中最远点的距离

    这里写图片描述

    以权为变量的最小二乘

    这里写图片描述

    对称矩阵最大特征值

    这里写图片描述

    矩阵范数

    这里写图片描述

    表示成一组仿射函数的逐点上确界

    建立凸函数的技巧:表示成一组仿射函数的逐点上确界

    复合函数

    标量复合

    这里写图片描述

    矢量复合

    这里写图片描述

    最小化

    这里写图片描述

    函数g的定义域是dom f在x方向上的投影。

    透视函数

    这里写图片描述

    共轭函数

    拟凸函数

    拟凸函数:定义域和所有下水平集都是凸集。

    拟凹函数:定义域和所有上水平集是凸集。

    拟线性函数:既是拟凸又是拟凹,定义域和所有水平集都是凸集。

    易知,凸函数是拟凸函数。但是拟凸函数不一定是凸函数。

    性质:拟凸性是凸性的扩展。在拟凸条件下,很多性质仍然成立。

    拟凸函数的Jensen不等式:

    f(θx+(1θ)y)max{f(x),f(y)}f(θx+(1−θ)y)≤max{f(x),f(y)}

    一阶条件

    这里写图片描述

    二阶条件

    这里写图片描述

    保拟凸运算

    待续

    对数-凹函数和对数-凸函数

    这里写图片描述

    一个函数是否是对数-凸函数,是指这个函数取对数之后是凸函数。

    一些例子:

    • 许多常见概率密度函数是对数-凹函数
    • 高斯概率密度函数的累积分布函数是对数-凹函数

    相关性质

    函数f二阶可微,则其是对数-凸函数,当且仅当

    这里写图片描述

    关于广义不等式的凸性

    把普通的不等式替换成广义不等式,则函数的单调性、凸性需要重新定义。

    关于广义不等式的单调性

    这里写图片描述

    关于广义不等式的凸性

    这里写图片描述

    参考文献

    《凸优化》

    展开全文
  • 前言遗传算法有很多优化和变形,本文将从最基本的遗传算法出发,以一个简单的优化问题作为例子来说明遗传算法的代码实现,比较适合已经学了相关理论知识的初学者进行实践学习。一、问题描述用GA求解一元函数的最大值...

    前言

    遗传算法有很多优化和变形,本文将从最基本的遗传算法出发,以一个简单的优化问题作为例子来说明遗传算法的代码实现,比较适合已经学了相关理论知识的初学者进行实践学习。

    一、问题描述

    用GA求解一元函数的最大值:

    f(x) = x sin(10πx) + 2.0, x∈[-1,2]
    

    二、编码

    变量x可以视为遗传算法的表现型形式,我们采用二进制编码形式。如果设定求解精度要精确到6位小数,由于区间长度为3,故将区间分为3*10^6等份,因为:

    2097152 = 2^21 < 3*10^6 < 2^22 = 4194304
    

    所以编码的二进制串长至少为22位。

    我们采用二进制编码,将一个二进制串与区间[Left,Right]间对应的实数值建立对应:

    假设二进制串b的十进制值为x’,则:

    x = (Right-Left)*x'/(2^22-1.0)+Left;
    

    三、产生初始种群

    我们通过随机产生一些个体(即随机产生一些二进制串),来初始化我们的种群。

    /*****function:generation the first popolation初始化群体*****/
    void GenerateInitialPopulation (void)
    { 
        int i,j;
        srand((unsigned)(time(NULL)));
        for (i=0;i<PopSize;i++)
        {
            for (j=0;j<CHROMLENGTH;j++)
            {
                population [i].chrom[j]=(random(10)<5)?'0':'1';
            }
            population [i].chrom[CHROMLENGTH]='\0';
        }
    }

    四、对种群进行评估

    /****function: evaluate population according to certain formula衡量群体*****/
    void EvaluatePopulation (void)
    {  
        CalculateObjectValue ();
        CalculateFitnessValue ();
        FindBestAndWorstIndividual ();
    }

    1.计算目标函数值

    /*****function: to decode a binary chromosome into a decimal integer*****/
    long DecodeChromosome (char *string,int point,int length)
    { 
        int i;
        long decimal=0L;
        char *pointer;
        for (i=0,pointer=string+point;i<length;i++,pointer++)
        { 
            decimal+=(*pointer-'0')<<(length-1-i);
        }
        return (decimal);
    }
    
    /***** function:to calculate object value f(x) = x sin(10πx) + 2.0 *****/
    void CalculateObjectValue (void)
    { 
        int i;
        long temp;
        double x;
        /*** rosenbrock function***/
        for (i=0;i<PopSize;i++)
        {       
            temp=DecodeChromosome (population[i].chrom,0,CHROMLENGTH);
            x=(Right-Left)*temp/(pow(2,CHROMLENGTH)-1.0)+Left;
                population[i].value=x*sin(10*PI*x)+2.0;//函数值
            population[i].x=x;//对应的自变量
        }
    }

    2.计算适应值

    在本例中,目标函数在定义域内大于0,而且求函数的最大值,所以我们直接引用目标函数作为适应度函数。

    /******function: to calculate fitness value *******/
    void CalculateFitnessValue (void)
    { 
        int i;
        for(i=0;i<PopSize;i++)
        {
            population[i].fitness=population[i].value;
        }
    }

    3.找出局部最优个体与局部最差个体,并更新全局最优个体

    /*****function to find out the best individual so far current generation*****/
    void FindBestAndWorstIndividual (void)
    { 
        int i;
        double sum=0.0;
        /*** find out the best and worst individual of this generation***/
        bestindividual=population[0];
        worstindividual=population[0];
        for(i=1;i<PopSize;i++)
        {
            if (population[i].fitness>bestindividual.fitness)
            {bestindividual=population[i];best_index=i;}
            else if(population[i].fitness<worstindividual.fitness)
            {worstindividual=population[i];worst_index=i;}
            sum+=population[i].fitness;
        }
        /***find out the best individual so far***/
        if (generation==0){ currentbest=bestindividual;}
        else 
        { 
            if(bestindividual.fitness>currentbest.fitness) {currentbest=bestindividual;}
        }
    }

    五、遗传操作

    我们按照轮盘赌的方式来选择子个体,对选出来的个体,两两进行交叉操作,随机选择一个交叉点。

    交叉之后进行变异操作,在二进制编码中,变异体现在位翻转上。

    /*****function: generate the next generation产生新种群*****/
    void GenerateNextPopulation (void)
    {  
        SelectionOperator ();
        CrossoverOperator ();
        MutationOperator ();
    }
    
    
    /*****function: to reproduce a chromosome by roulette wheel seclection*****/
    void SelectionOperator (void)
    { 
        int i,j,index;
        double p,sum=0.0;
        double cfitness[POPSIZE];  /*cumulative fitness value*/
        struct individual newpopulation[POPSIZE];
        /***calculate relative fitness***/
        for(i=0;i<PopSize;i++) {sum+=population[i].fitness;}
        for(i=0;i<PopSize;i++){cfitness[i]=population[i].fitness/sum;}
        /***calculate cumulative fitness***/
        for(i=1;i<PopSize;i++){cfitness[i]=cfitness[i-1]+cfitness[i];}
        /***selection operation***/
        for(i=0;i<PopSize;i++)
        {
            p=random(1000)/1000.0;
            index=0;
            while(p>cfitness[index]){index++;}
            newpopulation[i]=population[index];
        }
        for(i=0;i<PopSize;i++){population[i]=newpopulation[i];}
    }
    
    /*****function:crossover two chromosome by means of one-point crossover*****/
    void CrossoverOperator (void)
    { 
        int i,j;
        int index[POPSIZE];
        int point,temp;
        double p;
        char ch;
        /***make a pair of individual randomly***/
        for(i=0;i<PopSize;i++){index[i]=i;}
        for(i=0;i<PopSize;i++)
        {
            point=random(PopSize-i);
            temp=index[i];
            index[i]=index[point+i];
            index[point+i]=temp;
        }
        /***one-point crossover operation***/
        for(i=0;i<PopSize-1;i+=2)
        {
            p=random(1000)/1000.0;
            if(p<Pc)
            { 
                point=random(CHROMLENGTH-1)+1;
                for(j=point;j<CHROMLENGTH;j++)
                { 
                    ch=population[index[i]].chrom[j];
                    population[index[i]].chrom[j]=population[index[i+1]].chrom[j];
                    population[index[i+1]].chrom[j]=ch;
                }
            }
        }
    }
    
    /*****function: mutation of a chromosome*****/
    void MutationOperator (void)
    { 
        int i,j;
        double p;
        /*** bit mutation***/
        for(i=0;i<PopSize;i++)
        {
            for(j=0;j<CHROMLENGTH;j++)
            {
                p=random(1000)/1000.0;
                if(p<Pm){population[i].chrom[j]=(population[i].chrom[j]=='0')?'1':'0';}
            }
        }
    }

    六、进化

    /*****function:to perform evolution operation based on elitise mode. elitist model is to
           replace the worst individual of this generation by the current best one保留最优个体*****/
    void PerformEvolution (void)
    { 
        if(bestindividual.fitness>currentbest.fitness){currentbest=population[best_index];}
        else{population[worst_index]=currentbest;}
    }

    七、模拟结果

    我们设定种群大小为80,交叉概率为Pc=0.6,变异概率为Pm=0.001,按照标准的遗传算法SGA,在运行到200代时获得的最佳个体为:

    x=1.850549
    f(x)=3.850275 
    chromosome=1111001100111111001011
    

    这个个体对应的解与微分方程预计的最优解的情况吻合。

    附录

    完整代码

    # include <stdio.h>
    # include <stdlib.h>
    # include <time.h>
    # include <math.h>
    /****** the definition of constant******/
    # define PI 3.14159  
    # define POPSIZE 80
    /****** the definition of user data*****/
    # define LEFT -1
    # define RIGHT 2
    # define CHROMLENGTH 22
    
    # define random(x) rand()%x
    
      const int MaxGeneration=200;
      const double Pc=0.6;
      const double Pm=0.001;
    
    /***** the definition of data structure*****/
      struct individual
      { 
        char chrom[CHROMLENGTH+1];//基因 
        double x;   //自变量 
        double value;//目标函数值
        double fitness;//适应度
      };
    
    /***** the definition of global variables*****/
      int generation;
      int best_index;
      int worst_index;
      struct individual bestindividual;     //局部最优个体
      struct individual worstindividual;    //局部最差个体
      struct individual currentbest;        //全局最优个体 
      struct individual population[POPSIZE];//种群 
    
    /*****declaration of prototype 原型声明*****/
      void GenerateInitialPopulation (void);    //初始化种群 
      void GenerateNextPopulation (void);       //产生下一代种群 
      void EvaluatePopulation (void);           //评估 
      long DecodeChromosome (char *,int,int);   //对基因进行解码 
      void CalculateObjectValue (void);         //计算目标函数值 
      void CalculateFitnessValue (void);        //计算适应值 
      void FindBestAndWorstIndividual (void);   //寻找最优及最差个体 
      void PerformEvolution (void);             //进化 
      void SelectionOperator (void);            //选择 
      void CrossoverOperator (void);            //交叉 
      void MutationOperator (void);             //变异 
      void OutputTextReport (void);
    
    
    /***** main program*****/
    int main (void)
    { 
        generation=0;
        GenerateInitialPopulation ();       //调用初始群体函数  
        EvaluatePopulation ();          //第一次评估 
        while (generation<MaxGeneration)    //迭代一定代数 
        { 
            generation++;
            GenerateNextPopulation ();      //根据评估的结果来产生下一代 
            EvaluatePopulation ();          //对新一代种群进行评估 
            PerformEvolution ();            //进化 
            OutputTextReport ();
        }
        return 0;
    }
    
    /*****function:generation the first popolation初始化群体*****/
    void GenerateInitialPopulation (void)
    { 
        int i,j;
        srand((unsigned)(time(NULL)));
        for (i=0;i<POPSIZE;i++)
        {
            for (j=0;j<CHROMLENGTH;j++)
            {
                population [i].chrom[j]=(random(10)<5)?'0':'1';
            }
            population [i].chrom[CHROMLENGTH]='\0';
        }
    }
    
    /*****function: generate the next generation产生新种群*****/
    void GenerateNextPopulation (void)
    {  
        SelectionOperator ();
        CrossoverOperator ();
        MutationOperator ();
    }
    
    /****function: evaluate population according to certain formula衡量群体*****/
    void EvaluatePopulation (void)
    {  
        CalculateObjectValue ();
        CalculateFitnessValue ();
        FindBestAndWorstIndividual ();
    }
    
    /*****function: to decode a binary chromosome into a decimal integer*****/
    long DecodeChromosome (char *string,int point,int length)
    { 
        int i;
        long decimal=0L;
        char *pointer;
        for (i=0,pointer=string+point;i<length;i++,pointer++)
        { 
            decimal+=(*pointer-'0')<<(length-1-i);
        }
        return (decimal);
    }
    
    /***** function:to calculate object value f(x) = x sin(10πx) + 2.0 *****/
    void CalculateObjectValue (void)
    { 
        int i;
        long temp;
        double x;
        /*** rosenbrock function***/
        for (i=0;i<POPSIZE;i++)
        {       
            temp=DecodeChromosome (population[i].chrom,0,CHROMLENGTH);
            x=(RIGHT-LEFT)*temp/(pow(2,CHROMLENGTH)-1.0)+LEFT;
            population[i].value=x*sin(10*PI*x)+2.0;
            population[i].x=x;
        }
    }
    
    /******function: to calculate fitness value *******/
    void CalculateFitnessValue (void)
    { 
        int i;
        for(i=0;i<POPSIZE;i++)
        {
            population[i].fitness=population[i].value;
        }
    }
    
    /*****function to find out the best individual so far current generation*****/
    void FindBestAndWorstIndividual (void)
    { 
        int i;
        double sum=0.0;
        /*** find out the best and worst individual of this generation***/
        bestindividual=population[0];
        worstindividual=population[0];
        for(i=1;i<POPSIZE;i++)
        {
            if (population[i].fitness>bestindividual.fitness)
            {bestindividual=population[i];best_index=i;}
            else if(population[i].fitness<worstindividual.fitness)
            {worstindividual=population[i];worst_index=i;}
            sum+=population[i].fitness;
        }
        /***find out the best individual so far***/
        if (generation==0){ currentbest=bestindividual;}
        else 
        { 
            if(bestindividual.fitness>currentbest.fitness) {currentbest=bestindividual;}
        }
    }
    
    /*****function:to perform evolution operation based on elitise mode. elitist model is to
           replace the worst individual of this generation by the current best one保留最优个体*****/
    void PerformEvolution (void)
    { 
        if(bestindividual.fitness>currentbest.fitness){currentbest=population[best_index];}
        else{population[worst_index]=currentbest;}
    }
    
    /*****function: to reproduce a chromosome by roulette wheel seclection*****/
    void SelectionOperator (void)
    { 
        int i,j,index;
        double p,sum=0.0;
        double cfitness[POPSIZE];  /*cumulative fitness value*/
        struct individual newpopulation[POPSIZE];
        /***calculate relative fitness***/
        for(i=0;i<POPSIZE;i++) {sum+=population[i].fitness;}
        for(i=0;i<POPSIZE;i++){cfitness[i]=population[i].fitness/sum;}
        /***calculate cumulative fitness***/
        for(i=1;i<POPSIZE;i++){cfitness[i]=cfitness[i-1]+cfitness[i];}
        /***selection operation***/
        for(i=0;i<POPSIZE;i++)
        {
            p=random(1000)/1000.0;
            index=0;
            while(p>cfitness[index]){index++;}
            newpopulation[i]=population[index];
        }
        for(i=0;i<POPSIZE;i++){population[i]=newpopulation[i];}
    }
    
    /*****function:crossover two chromosome by means of one-point crossover*****/
    void CrossoverOperator (void)
    { 
        int i,j;
        int index[POPSIZE];
        int point,temp;
        double p;
        char ch;
        /***make a pair of individual randomly***/
        for(i=0;i<POPSIZE;i++){index[i]=i;}
        for(i=0;i<POPSIZE;i++)
        {
            point=random(POPSIZE-i);
            temp=index[i];
            index[i]=index[point+i];
            index[point+i]=temp;
        }
        /***one-point crossover operation***/
        for(i=0;i<POPSIZE-1;i+=2)
        {
            p=random(1000)/1000.0;
            if(p<Pc)
            { 
                point=random(CHROMLENGTH-1)+1;
                for(j=point;j<CHROMLENGTH;j++)
                { 
                    ch=population[index[i]].chrom[j];
                    population[index[i]].chrom[j]=population[index[i+1]].chrom[j];
                    population[index[i+1]].chrom[j]=ch;
                }
            }
        }
    }
    
    /*****function: mutation of a chromosome*****/
    void MutationOperator (void)
    { 
        int i,j;
        double p;
        /*** bit mutation***/
        for(i=0;i<POPSIZE;i++)
        {
            for(j=0;j<CHROMLENGTH;j++)
            {
                p=random(1000)/1000.0;
                if(p<Pm){population[i].chrom[j]=(population[i].chrom[j]=='0')?'1':'0';}
            }
        }
    }
    
    /*****function: output the results of current population*****/
    void OutputTextReport (void)
    { 
        int i;
        double sum;
        double average;   /***average of population object value***/
        /*** calculate average object value***/
        sum=0.0;
        for(i=0;i<POPSIZE;i++){sum+=population[i].value;}
        average=sum/POPSIZE;
        /***print results of this population ***/
        printf("gen=%d, avg=%f, x=%f, best=%f ",generation,average,currentbest.x,currentbest.value);
        printf("chromosome=");
        for(i=0;i<CHROMLENGTH;i++){printf("%c",currentbest.chrom[i]);}
        printf("\n");
    }
    展开全文
  • 优化、最优化、凸集、凸函数

    千次阅读 2018-11-01 20:51:14
    那么,在重建算法中,如何对问题建立数学模型并求解,这就涉及到了最优化或凸优化的相关知识。 在压缩感知中,大部分情况下都转换为凸优化问题,并通过最优化方法来求解,因此了解相关知识就显得尤为重要了。 主要...

    原文:https://www.cnblogs.com/AndyJee/p/5048735.html

    我们知道压缩感知主要有三个东西:信号的稀疏性,测量矩阵的设计,重建算法的设计。那么,在重建算法中,如何对问题建立数学模型并求解,这就涉及到了最优化或凸优化的相关知识。

    在压缩感知中,大部分情况下都转换为凸优化问题,并通过最优化方法来求解,因此了解相关知识就显得尤为重要了。

    主要内容:

    1. 问题引出
    2. 凸集
    3. 凸函数
    4. 凸优化
    5. 最优化

    1、问题引出

    在n维空间中,对于任意两个点,对于0<=μ<=1,则表达式μx+(1-μ)y表示xy连线之间的所有点。

    证明略。

    2、凸集

    定义:

    对于某集合中的任意x, y两个点,若x和y连线之间的所有点(0<=μ<=1μx+(1-μ)y)仍属于这个集合,则称此集合为凸集

    维基百科:http://en.wikipedia.org/wiki/Convex_set

    直观的几何表示:

    左边的是凸集,右边的不是凸集,因为右边的集合中任意两点x和y连线之间的所有点有时不属于这个集合(右图中的连线)。

    3、凸函数

    定义:

    对于f(x)是定义在某凸集(非空的,空集也被规定为凸集)上的函数,对于凸集中的任意两点x1和x2,若

    f[μx1+(1-μ)x2]<=μf(x1)+(1-μ)f(x2)

    则称函数f(x)为凸函数

    维基百科:http://en.wikipedia.org/wiki/Convex_function

    直观的几何表示:

    也就是说两点对应的函数值f(x1)和f(x2)的之间的连线(μf(x1)+(1-μ)f(x2))大于等于相应的(即同一个μ值)两点之间连线(μx1+(1-μ)x2)所对应的函数值f[μx1+(1-μ)x2]

    这其实应叫下凸。

    如果把上面不等式中的等号去掉,即

    f[μx1+(1-μ)x2]<μf(x1)+(1-μ)f(x2) ,其中0<μ<1

    则称f(x)为严格凸函数。

    凸函数的判定方法:

    1. 求导计算判断:

      一阶充要条件:

      其中要求f一阶可微。

      二阶充要条件:

      其中要求f二阶可微,表示二阶导数需大于0才是凸函数。

    2. 常用函数分析法:

      指数函数是凸函数;

      对数函数是凹函数,然后负对数函数就是凸函数;

      对于一个凸函数进行仿射变换,可以理解为线性变换,结果还是凸函数;

      二次函数是凸函数(二次项系数为正);

      高斯分布函数是凹函数;

      常见的范数函数是凸函数;

     多个凸函数的线性加权,如果权值是大于等于零的,那么整个加权结果函数是凸函数。

    4、凸优化

    定义:

    同时满足如下两个条件的优化问题称为凸优化:

    1)目标函数(objective function)是凸函数;

    2)可行集合(feasible set)必须是凸集;

    即在凸集上寻找凸函数的全局最值的过程称为凸优化

    对于一下的优化问题:

    若目标函数f(x)是凸函数且可行集R是凸集,则称这样的问题为凸优化问题

    或者:

    如果目标函数f(x)和共l个约束函数gi(x)都是凸函数,则称这样的问题为凸优化问题

    实际上,可以证明,约束函数gi(x)都是凸函数,则它的可行集是凸集。

    凸优化的特点:

    1)如果一个实际的问题可以被表示成凸优化问题,那么我们就可以认为其能够得到很好的解决。

    2)还有的问题不是凸优化问题,但是凸优化问题同样可以在求解该问题中发挥重要的左右。比如松弛算法和拉格朗日松弛算法,将非凸的限制条件松弛为凸限制条件。

    3)对于凸优化问题来说,局部最优解就是全局最优解。

    4)若f(x)在非空可行集R上是严格凸函数,则全局极值点是唯一的。

    也就是说如果把一个非凸优化问题转化为凸优化问题(松弛算法),则若求得一个局部最优解即为得到了全局最优解(若目标函数在可行集上是严格凸函数,则此解还是唯一的),并且凸优化问题能够比较好的得解决,因此在看压缩感知的文献时经常会看到如何如之何修改一下约束条件使之变为一个凸优化问题。

    非凸优化问题如何转化为凸优化问题:

    1)修改目标函数,使之转化为凸函数

    2)抛弃一些约束条件,使新的可行域为凸集并且包含原可行域

    实际建模中判断一个最优化问题是不是凸优化问题的方法:

    1、目标函数f如果不是凸函数,则不是凸优化问题

    2、决策变量x中包含离散变量(0-1变量或整数变量),则不是凸优化问题

    3、约束条件写成g(x)<=0时,g如果不是凸函数,则不是凸优化问题

    5、最优化

    最优化问题:

    线性规划

    二次规划

    二次约束的二次规划

    半正定规划

    最优化手段:

      梯度上升(下降)法

      牛顿法 / 拟牛顿法

      坐标下降法:

    6、参考文章

    http://blog.csdn.net/jbb0523/article/details/40742955

    http://m.blog.csdn.net/blog/njustzj001/47400411

    展开全文
  • 遗传算法 简单函数优化

    千次阅读 2015-02-02 11:06:22
    %注意程序中num2gray函数和gray2num函数可以参照我上面的另外两个博文中有代码 %%初始化参数 L=16; %编码为16位二进制数 N=32; %初始种群规模 M=48; %M个中间体,运用算子选择出M/2对母体,进行交叉;对M个中间体...
  • 优化问题及其分类

    万次阅读 多人点赞 2016-02-24 22:24:52
    归纳而言,最优化问题分为函数优化问题和组合优化问题两大类,其中函数优化的对象是一定区间的连续变量,而组合优化的对象则是解空间中的离散状态。 一、函数优化问题函数优化问题通常可描述为:令S S为R n R^n上...
  • 3 损失函数优化

    千次阅读 2017-06-07 20:42:37
    为了描述之前建立的线性分类器的分类效果,我们引入的损失函数,顾名思义,损失函数越大误差也就越大。 在下图的任务中,将测试图片猫、车和青蛙输入网络,输出了一系列的数值,如下表。 很显然我们希望图片对应的...
  • 当一个大型系统在建立时,会发现,很多的SQL操作是有重叠的,个别计算是相同的,比如:业务系统中,计算一张工单的计算方式。当遇到这些情况时,我们运用存储过程就是一个非常棒的优化啦。 本文章结构:(1)存储...
  • 代码优化-之-Base64编码函数的极限优化挑战 HouSisong@GMail.com 2007.07.27 tag:速度优化,Base64,CPU缓存优化,代码优化,查找表,汇编,SSE、SSE2优化,并行 摘要: Base64编码是很常用的一种把二进制数据转换为...
  • Lingo函数

    千次阅读 2016-02-16 14:33:01
    Lingo软件中存在各种各样的运算符及相关函数,能够有效的帮助我们建立并求解复杂的优化模型。 Lingo中包含9个类型的函数: 基本运算符:包含算术运算符,逻辑运算符和关系运算符 数学函数:三角函数和常规的数学...
  • MySQL的sum函数优化

    万次阅读 2014-01-21 11:15:22
    在mysql优化的方法中,有这么两条: 经常同时存取多列,且每列都含有重复值可考虑建立组合索引; 组合索引要尽量使关键查询形成索引覆盖,其前导列一定是使用最频繁的列。 所以你可以试试下面方法:在STATUS和...
  • 目标函数定义最大似然...最大似然估计是建立在这样的思想上:已知某个参数能使这个样本出现的概率最大,我们当然不会再去选择其他小概率的样本,所以干脆就把这个参数作为估计的真实值。求最大似然函数估计值的一般步
  • 优化问题综述

    万次阅读 多人点赞 2017-03-19 18:58:47
    优化问题一般可分为两大类:无约束优化问题和约束优化问题,约束优化问题又可分为含等式约束优化问题和含不等式约束优化问题。 无约束优化问题 含等式约束的优化问题 含不等式约束的优化问题 2 求解策略 针对...
  • 今天来学习变量优化问题。寻找使成本函数最小的题解。适用于题解相互独立的情况,设计随机优化算法、爬山法、模拟退火算法、遗传算法。问题场景: 所有乘客从不同的地方飞到同一个目的地,服务人员等待所有人到来...
  • 第三章 损失函数优化课时1 损失函数 在上一章的课程中,我们讨论了识别问题,并尝试了数据驱动的方式,讲到了图像分类的难点在哪里;同时讨论了K近邻分类器以便作为介绍数据驱动理念的一个简单例子,最后还讨论了...
  • 数学建模之优化问题

    万次阅读 2019-01-22 23:37:13
    采用优化方法时,要明确4个要素,决策变量,目标函数,约束条件是什么。下面进行阐述3种类型的优化处理以及matlab代码。 线性规划问题 用matlab处理一般的线性规划问题的标准型为: min z=∑j=1ncjxi\sum_{j=1}^...
  • 3.1基本性质和例子 定义 扩展值延伸 一阶条件 二阶条件 例子 下水平集 上境图 ...函数f是凸函数,当且仅当在与函数f的定义域S相交的任何直线上,f均是凸的。 当且仅当g(t)是凸的,f(x)是凸的...
  • 文章目录1、计算几何是研究什么的?2、计算几何理论中(或凸集中)过两点的一条直线的表达式,是如何描述的?与初中数学中那些直线方程... 如何判别一个函数是凸函数?f(x)=x^3 函数是凸函数吗?7、什么是“凸规划”...
  • 与通常特征学习算法试图建模训练数据的分布的做法不同,Sparse Filtering 直接对训练数据的特征分布进行分析,在所谓“好特征”的指导下构建目标函数来进行优化,其中只涉及一个可调参数。本文将主要讨论两个问题:...
  • 文章目录机场出租车优化问题摘 要问题的重述问题的分析2.1问题一的分析2.2问题二的分析2.3问题三的分析2.4问题四的分析符号说明模型的建立与求解5.1 问题一模型的建立与求解5.2模型二的建立与求解5.3问题三5.4问题四...
  • 优化模型的时候,当模型评价指标不再变化的时候,有可能是学习率已经不适合当前的模型,需要调小一些。在训练初期,学习率设置大一些可以加速模型训练;在模型后期,将学习率调小一些,可以使得模型更加精确。我们...
  • 步骤一 步骤二 运行,出现下图,不用管,接着做第步骤三 步骤三 步骤4: 点击strat。出现如下两图,当x=0,y=1,s最小值为-5
  • Oracle 建立索引及SQL优化

    千次阅读 2018-02-11 09:53:22
    一、建立数据库索引: 索引有单列索引和复合索引之说。 建设原则:  1、索引应该经常建在Where 子句经常用到的列上。如果某个大表经常使用某个字段进行查询,并且检索行数小于总表行数的5%。则应该考虑。  2、...
  • 我们之前讲了我们对于一张图片,我们对其进行打分,代表它被分为某一类的可能性,那么我们需要建立一个损失函数来对这个分类器的好坏进行衡量 我们定义SVM损失函数有如下形式。SVM只是一个二元分类器,我们将其...
  • 建立函数索引后,又发现查询语句属于模糊搜索(即 like ‘%XXX%’),一般索引在模糊搜索下会全表扫描。但此函数索引不是要用其索引的快速筛选功能,而是要用其函数内部计算的过程(直接使用索引值而不用每次查询时再...
  • MySQL---如何对max()函数进行优化

    千次阅读 2018-05-17 20:41:44
    如果我们在alarming_time字段上建立一个索引,那么,SQL就会大大优化 现在再来看看 SELECT tables optimized away 说明MySQL根本没有遍历表或索引就返回数据了,myisam已经保存了记录的总数,直接返回结果。此...
  • 怎样优化J2ME程序当中的paint()函数

    千次阅读 2005-07-19 14:36:00
    优化J2ME中的paint()函数林刚 { lirincy@163.com, 引用须注明出处作者} 关键字:优化paint J2ME, 局部刷新,局部重画,图片 我们经常会遇到这样的问题,在模拟器上跑得很好的程序在实际的手机上却很慢,甚至运行...
  • libsvm 核函数 交叉验证 参数优化

    万次阅读 2013-11-29 16:53:49
    关于各种模型优化函数,请参考: http://pan.baidu.com/share/home?uk=875657448#category/type=0 -t kernel_type : set type of kernel function (default 2)  0 -- linear: u'*v  1 -- polynomial: ...
  • 我们这里提到的最优化问题通常是指对于给定的某一函数,求其在指定作用域上的全局最小值(因为最小值与最大值可以很容易转化,即最大值问题可以转化成最小值问题)。提到KKT条件一般会附带的提一下拉格朗日乘子。对学...
  • select clazz,sum(score) from table_a group by clazz 此时要建立复合索引在 clazz 和 socre这两个字段

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 314,340
精华内容 125,736
关键字:

优化问题建立函数