【工程优化】一维搜索方法

一维搜索方法的分类如下:

这篇文章主要讲解黄金分割法、二分法、牛顿法这三种一维搜索方法。黄金分割法只用到原函数,二分法用到函数的一阶导,牛顿法用到函数的二阶导。由于本文主要对研一上学期的课程中的部分算法进行程序实现,理论部分大多参考上课的课件

黄金分割法

基本概念:

算法思想:

算法流程图及优缺点如下:

二分法

 基本思想:

牛顿法

基本思想:

算法流程图:

具体实现:

下面我们通过程序具体实现,在程序中,我们设置原函数都是f(x)=sinx/x,搜索区间都是[0,1],牛顿法中假设初始值设为1,具体程序如下所示

#include<stdio.h>
#include<math.h>
/********************函数的定义、一阶导、二阶导的模块 BEGIN*************************/
/*****************************输入:x为自变量
输出:x自变量对应的函数值
\*****************************/
double Function(double x)
{
    return (x-0.5)*(x-0.5);//这里填写函数式f(x),根据自己的函数修改
}
/*****************************输入:x为自变量
输出:x自变量对应的一阶导数值
\*****************************/
double Derivative(double x)//求函数的一阶导数
{
    double eps=0.0000001;//精度控制
    double dx=0.5;//设置初始的间隔,太大需要迭代多次,太小缺乏精度
    double dy=Function(x+dx)-Function(x);//函数值的增量
    double dd1=dy/dx;//导数
    double dd2=0;//dx变化时的导数
    dx=dx/2;//不断地减少x的增量
    dy=Function(x)-Function(x+dx);
    dd2=dy/dx;//计算新的导数值
    while(abs(dd1-dd2)>eps)//当相邻两次的导数值小于精度时终止迭代,得到导数
    {
        dd1=dd2;
        dx=dx/2.0;
        dy=Function(x+dx)-Function(x);
        dd2=dy/dx;
    }
    return dd2;
}
//求函数的2阶导数,与求一阶导数的原理一样,只需要把求函数值的函数Function换成求一阶导数的函数Derivative
/*****************************输入:x为自变量
输出:x自变量对应的二阶导数值
\*****************************/
double Derivative2(double x)
{
    double eps=0.00000001;
    double dx=0.5;
    double dy=Derivative(x+dx)-Derivative(x);
    double dd1=dy/dx;
    double dd2=0;
    dx=dx/2;
    dy=Derivative(x)-Derivative(x+dx);
    dd2=dy/dx;
    while(abs(dd1-dd2)>eps)
    {
        dd1=dd2;
        dx=dx/2.0;
        dy=Derivative(x+dx)-Derivative(x);
        dd2=dy/dx;
    }
    return dd2;
}
/********************函数的定义、一阶导、二阶导的模块  END*************************/
/******************************************输入:a,b为区间的上下限,n为最大的迭代次数
输出:打印函数最小值及对应的自变量x
\******************************************/
void GoldenSection(double a,double b,int n)//黄金分割法
{
    double l=a+0.382*(b-a);
    double h=a+0.618*(b-a);
    double region=b-a;

    double fl;
    double fh;
    int num=1;//迭代次数

    while(region>0.0000000001&&num<n)
    {
        fl=Function(l);
        fh=Function(h);
        if(fl>fh)
        {
            a=l;
            l=h;
            h=a+0.618*(b-a);
        }
        else
        {
            b=h;
            h=l;
            l=a+0.382*(b-a);
        }
        num++;
        region=abs(b-a);
    }
    if(num==n)
        printf("找不到最小值");
    else
    {
        printf("黄金分割法:x=%f时,最小值f(x)=%f",(a+b)/2,Function((a+b)/2));

    }
}
/******************************************输入:a,b为区间的上下限
输出:打印函数最小值及对应的自变量x
\******************************************/
void Dichotomy(double a,double b)//二分法
{
    double eps=0.0000001;
    double x=(a+b)/2;
    double region=b-a;
    double fxDerivative= Derivative(x);
    while(region>0.0000001&&abs(fxDerivative)>eps)
    {
        fxDerivative= Derivative(x);
        if(fxDerivative>eps)
            b=x;
        if(fxDerivative<-eps)
            a=x;
        x=(a+b)/2;
        region=abs(b-a);
    }
    printf("\n\n二分法:x=%f时,f(x)=%f\n",x,Function(x));
}
/******************************************输入:a,b为区间的上下限,x1是初始值
输出:打印函数最小值及对应的自变量x
\******************************************/
void Newton(double a,double b,double x1)
{
    double eps=0.0000001;
    double x=x1;
    double d1=Derivative(x1);//一阶导
    double d2;//二阶导
    while(abs(d1)>eps)
    {
        d2=Derivative2(x);
        if(d2<0)
            printf("二阶导小于0,无法求解");
        else
        {
            x=x-d1/d2;//x迭代公式
            d1=Derivative(x);
        }
    }
    printf("\n牛顿法:x=%f时,f(x)=%f\n\n",x,Function(x));
}
void main()
{
    GoldenSection(0,1,100000);//黄金分割法

    Dichotomy(0,1);//二分法
    Newton(0,1,1);//牛顿法
}

运行结果如下图:

原文:http://blog.csdn.net/tengweitw/article/details/42925669

作者:nineheadedbird

时间: 2024-10-12 17:15:05

【工程优化】一维搜索方法的相关文章

工程优化方法中的“最速下降法”和“DFP拟牛顿法”的 C 语言实现

这个小程序是研一上学期的“工程优化”课程的大作业.其实这题本可以用 MATLAB 实现,但是我为了锻炼自己薄弱的编码能力,改为用 C 语言实现.这样,就得自己实现矩阵的运算(加减乘除.求逆.拷贝):难点是求偏导,通过查资料,发现可以通过导数定义,即取极限的方法,来逐步逼近求得梯度:另外,没法做到输入任意公式,只能将公式硬编码为函数,而求导函数需要传入公式,就直接传入函数指针了.思考.编码.调试.测试共耗费两周左右时间,完成于 2013/01/10.虽然为了认真做这个大作业而耽误了期末考试的复习,

数值算法:无约束优化之一维搜索方法之黄金分割法、斐波那契数列法

目标函数为一元单值函数f:R->R的最小化优化问题,一般不会单独遇到,它通常作为多维优化问题中的一个部分出现,例如梯度下降法中每次最优迭代步长的估计. 一维搜索方法是通过迭代方式求解的,这不同于我们人脑的直接通过解表达式求解方法.迭代算法是从初始搜索点x(0)出发,产生一个迭代序列x(1),x(2),....在第k=0,1,2,...次迭代中,通过当前迭代点x(k)和目标函数 f 构建下一个迭代点x(k+1).某些算法可能只需要用到迭代点处的目标函数值,而另一些算法还可能用到目标函数的导数 f'

WEB前端性能优化常见方法

web前端是应用服务器处理之前的部分,前端主要包括:HTML,CSS,javascript,image等各种资源,针对不同的资源有不同的优化方式. 1. 内容优化 (1)减少HTTP请求数:这条策略是最重要最有效的,因为一个完整的请求要经过DNS寻址,与服务器建立连接,发送数据,等待服务器响应,接收数据这样一个消耗时间成本和资源成本的复杂的过程. 常见方法:合并多个CSS文件和js文件,利用CSS Sprites整合图像,Inline Images(使用 data:URL scheme在实际的页

从代码方面来探讨前端优化的方法

< DOCTYPE html PUBLIC -WCDTD XHTML TransitionalEN httpwwwworgTRxhtmlDTDxhtml-transitionaldtd> 从代码方面来探讨前端优化的方法:1.减少http请求数图片,css,script,flash,等等这些都会增加http请求数,减少这些元素的数量能减少响应时间.CSS Sprites技术能减少图片的请求数,把零散的小图片放到一起,运用background-position来改变背景图片的位置,前提是html元

让你提前认识软件开发(51):VC++集成开发环境中Linux下Pclint工程的配置方法及常见错误修改

第3部分 软件研发工作总结 VC++集成开发环境中Linux下Pclint工程的配置方法及常见错误修改 [文章摘要] Pclint是一种C/C++软件代码静态分析工具.它是一种更加严格的编译器,能够发现普通编译器所不能发现的代码中的很多问题,因此被广泛应用于软件开发项目中. 本文介绍了如何在VC++集成开发环境中配置Linux下的Pclint工程,给出了C语言中pclint规则A检查的常见错误,并描述了对应的修改办法. [关键词] VC++  Pclint  配置  操作  修改 1. 前言 P

Erlang服务器内存吃紧的优化解决方法

问题提出:服务器100万人在线,16G内存快被吃光.玩家进程占用内存偏高 解决方法: 第一步: erlang:system_info(process_count). 查看进程数目是否正常,是否超过了erlang虚拟机的最大进程数. 第二步: 查看节点的内存瓶颈所在地方 > erlang:memory(). [{total,2099813400}, {processes,1985444264}, {processes_used,1985276128}, {system,114369136}, {a

vs2010缩小MFC工程大小的方法

MFC工程文件编译运行之后的工程大小往往都是100M兆以上,下面介绍一下vs2010中缩小MFC工程大小的方法. 工程文件缩小前的大小:120M. 方法分为两步: (1)清理解决方案:在vs2010菜单栏点击"生成"----->"清理解决方案". (2)在工程文件所在的文件目录下,删除数据库文件. 工程文件缩小完成,完成后的大小:362KB. 说明:在网上查阅资料,有提到关闭vs2010的intellisence提示的,但是感觉效果不好,而且关闭了vs2010

网易视频云技术分析:IOS工程常见问题解决方法

网易视频云是网易推出的视频云服务,目前已经y广泛应用于在线教育.秀场直播.远程医疗.企业协作等领域.现在,网易视频云的技术专家们给大家分享一则移动APP测试技术文:IOS工程常见问题解决方法. 最近在做IOS测试时,碰到了几个环境引起的问题,主要是开发工具新版本及IOS系统新版本特性导致.现挑取两个比较典型的问题来分享给大家. 1. Xcode版本引出的问题 问题描述:开发提测时,创建的工程是在xcode6版本上创建的,而测试环境使用新的版本Xcode7,将开发提测工程导入后进行编译报如下错误:

非凸优化的方法

关于非凸优化的方法, https://blog.csdn.net/kebu12345678/article/details/54926287 提到,可以把非凸优化转换为凸优化,通过修改一些条件. 非凸优化问题如何转化为凸优化问题的方法:1)修改目标函数,使之转化为凸函数2)抛弃一些约束条件,使新的可行域为凸集并且包含原可行域 而 https://blog.csdn.net/R1uNW1W/article/details/79000042 的论文提到了解决非凸优化问题的几种方法: 1.利用传统的凸