精华内容
下载资源
问答
  • 什么是程序的局部性原理

    千次阅读 2019-12-02 11:38:14
    了解局部性原理,可以有效的帮助我们理解和写出更好的代码,对于局部性原理可能有的小伙伴知道,有的小伙伴不知道,知道的小伙伴就当做复习知识点,不知道的小伙伴也没关系,接着往下看就知道了。 02、什么是局部性...

    01、前言

    作为有追求的程序员,我们日常在写代码的时候往往都会运用很多奇技淫巧,不单单是为了炫耀我们的技术,更是为了追求更高的效率。了解局部性原理,可以有效的帮助我们理解和写出更好的代码,对于局部性原理可能有的小伙伴知道,有的小伙伴不知道,知道的小伙伴就当做复习知识点,不知道的小伙伴也没关系,接着往下看就知道了。

    02、什么是局部性原理

    说到局部性原理,那我们首先要知道什么是局部性原理,局部性原理分为两部分:

    • 时间局部性:指的是在程序运行过程中最近被引用到的存储器位置在程序执行后期还会被多次引用到的可能性很大。
    • 空间局部性:指的是程序运行过程中如果一个存储器的位置被引用,那么在程序执行后期该存储器附近的位置被引用的可能性很大。

    简单来说就是一个变量在程序运行过程中,如果被引用过一次,那后续很有可能会再被引用到;一个变量被访问到过后,这个变量所在的位置附近的位置很有可能在程序后续运行中被访问到。

    03、示例

    上面是通过理论来说明的,下面我们通过一段代码来看看局部性y原理

    public int sum(int[] array) {
            int sum = 0;
            for (int i = 0; i < array.length; i++) {
                sum = sum + array[i];
            }
            return sum;
    }
    

    从上面的这段代码来看,就是一个很简单的数组元素求和,这里我们主要看 sum 和 array 两个变量,我们可以看到 sum 在每次循环中都会用到,另外它只是一个简单变量,所以我们可以看到,sum 是符合我们上面提到的时间局部性,再访问一次后还会被继续访问到,但是它不存在我们所说的空间局部性了。

    相反的,array 数组中的每个元素只访问一次,另外数组底层的存储是连续的,所以 array 变量符合我们上面提到的空间局部性,但是不符合时间局部性。

    这只是局部性原理的简单示例,对于局部性原理还有很多地方会用到,我们如果能熟练的掌握和使用,对我们的帮助会很大的。

    04、相关应用

    4.1、CPU 缓存

    上面的示例其实很简单,相信大家都能理解,另外局部性原理其实在我们日常使用的软件中随处可见,并且在操作系统中也少不了。我们知道 CPU 的速度是非常快的,而且 CPU 与内存之间有多级缓存,如下图(图片来源于网络)

    image-20191129115010857.png

    为了充分的利用 CPU,操作系统会利用局部性原理,将高频的数据从内存中加载的缓存中,从而加快 CPU 的处理速度。

    4.2、广义局部性

    其实我们的局部性原理不单单是上面提到的狭义性的局部性,还可以是广义的局部性。我们系统里面的热点数据,CDN 数据,微博的热点流量等等这些都利用了局部性原理。只是我们可能没有意识到而已,实际上已经在使用了。我们会通过 Redis 缓存热点数据,会通过 CDN 提前加载图片或者视频资源,等等,都是因为这些数据本身就符合局部性原理,合理的利用局部性可以得到了能效、成本上的提升。

    4.3、利弊结合

    任何事情都是多面性的,局部性原理虽然我们使用起来很不错,可以提高系统性能,但是在有些场景下,我们是需要避免局部性原理的出现的。或者说出现了这种情况,我们需要人工处理。我们可以试想一下,如果在我们的一个大数据处理平台上,由于局部性原理的存在,导致我们部分节点数据庞大运算吃力,部分节点数据量小十分空闲,这种情况自然是不合理,我们就需要把数据按照业务场景进行重新分配,以达到整个集群的最大利用。

    05、总结

    今天给大家介绍了一下局部性原理,我们提到了时间局部性和空间局部性,通过一个代码示例和几个业务场景给大家简单介绍了局部性的使用。最后也提到局部性原理有利也有弊,我们需要根据业务场景和需求合理话的使用。

    展开全文
  • 局部变量

    2018-05-17 18:03:57
    局部变量(Local variables)在程序中只在特定过程或函数中可以访问的变量。局部变量是相对于全局变量而言的。在C++、C#、Ruby这些面向对象语言中,一般只使用局部变量。面向对象编程是现在普遍采用的是软件开发方法...

            局部变量(Local variables)指在程序中只在特定过程或函数中可以访问的变量。局部变量是相对于全局变量而言的。在C++、C#、Ruby这些面向对象语言中,一般只使用局部变量。面向对象编程是现在普遍采用的是软件开发方法,因此无需考虑是局部变量还是全局变量,说到变量,往往都是局部变量。

    重名现象

            在C等面向过程语言中,局部变量可以和全局变量重名,但是局部变量会屏蔽全局变量。在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。

    应用


    在Java等面向对象语言中,也可能出现多个局部变量重名的情况。例如一个方法的形式参数与类成员的名字相同,这时形式参数会把类成员屏蔽,如果要访问类成员,应该用this关键字。

    折叠

    局部变量和全局变量


    在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。

    全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。

    当全局变量与局部变量同名时:

    在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。

    案例1:
    void main()
    {
            int test = 0; //局部变量
            printf("%d", test);
    }
     
    案例2:
    public class Clothes 
    { 
    String id; //实例变量 
    private String colorType; //实例变量 
    private int size; //实例变量 
    private static String depart; //类变量 
    final String design="yangzi"; //常量 
    }
    代码中的实例变量、类变量、常量都属于成员变量,那么其区分的依据是什么?这与变量的修饰符有关系,也就是上面代码中的private、static、final等修饰符。
    代码中的实例变量、类变量、常量都属于成员变量,那么其区分的依据是什么?这与变量的修饰符有关系,也就是上面代码中的private、static、final等修饰符。

    修饰符   说明   
    public   成员变量可以被项目中的任何方法访问,建议尽量少用   
    protected   不在同一个包中的类不能访问,但子类可以访问   
    private   只能在同一个类中使用   
    static   类变量,其值为该类的所有对象共享,不会因类的对象不同而不同   
    final   最终成员变量,其值保持不变,即常量   
    transient   当对象被持久化时(例如写入数据库),该成员变量的值不需要保存   
    volatile   同步多线程访问的成员变量的值,以便使不同的线程总是得到 该成员变量的同一个值。

            int a=1;

    局部变量和全局变量在一起时时局部变量优先


    int main()
    {
    int a=2;
    cout<<a;
    return 0;
    }
    就是类似这样的 例子 ,你在 main函数 外定义了一个 全局变量 a,在main 内部 又定义了一个 变量 名也是a的 局部变量 ,那么你在main中用cout输出的时候就是输出了局部变量a的值,要输出全局变量a的值时则要使用::a,实际上是局部变量将全局变量屏蔽了,可以看做局部变量的优先于全局变量


    展开全文
  • 简介=========================================================================================...名字的作用域的是知道该名字的程序文本去(哪些地方可以用); 对象的生命期则是在程序执行过程中对象存在的时间

    简介

    ==============================================================================================================

    一、局部对象

    • 在C++中,每个名字都有作用域,而每个对象都有生命期;

    • 名字的作用域指的是知道该名字的程序文本区(哪些地方可以用)

    • 对象的生命期则是在程序执行过程中对象存在的时间(什么时候可以用,什么时候不可以了);

    • 在函数中定义的形参和变量的名字只位于函数的作用域中,这些名字只在函数体中可见,通常,变量名从声明或定义的地方开始到包围它的作用域结束处都是可用的。

    1、自动对象

    • 默认情况下,局部变量的生命期局限于所在的函数的每次执行期间。

    • 只有当定义它的函数被调用时才存在的对象称为自动对象

    • 自动对象在每次调用函数时创建和撤销。

    • 局部变量所对应的自动对象在函数控制经过变量定义语句时创建。

    • 如果在定义时提供了初始化式,那么每次创建对象时,对象都会被赋予指定的初值。

    • 对于未初始化的内置类型局部变量(局部变量不会默认初始化的,全局变量就会),其初值不确定,函数调用结束时,自动对象就会被撤销

    • 形参也是自动对象,形参所占用的存储空间在调用函数时创建,在函数结束时撤销。当函数结束时,会释放它的局部存储空间,而且,在函数结束后,自动对象和形参的值都不能再访问 了;

    • -

    2、静态局部对象

    • 一个变量如果位于函数的作用域内,但生命期却跨越了这个函数的多次调用,这种变量很有用 ,往往定义为static(静态的)

    • static局部对象确保不迟于在程序执行流程第一次经过该对象的定义语句时进行初始化,这种对象一旦被创建,在程序结束前都不会撤销。

    • 当定义静态局部对象的函数结束时,静态局部对象不会撤销。在该函数被多次调用的过程中,静态局部对象会持续存在并保持它的值。

    size_t count_calls(){
        static size_t ctr=0;//定义一个静态的局部的变量,而且该变量已经被初始化
        return ++ctr;
    }
    
    int main(){
      for(size_t i=0;i!=10;i++)
      cout<<count_calls()<<endl;//依次输出1--10
      return 0;
    }
    //在第一次调用函数count_calls之前,ctr就已经创建并赋予初值0.每次函数调用都使ctr加1,并且返回其当前值。在执行函数count_calls时,变量ctr就已经存在并且保留上次调用该函数时的值,因此第二次调用时,ctr的值为1,第三次为2.。
    //如果去掉static ,那么结果就是10个1.因为每次调用结束ctr就被撤销了,再次调用的时候又重新建立并初始化。

    习题 7.27 (important)

    解释形参、局部变量和静态局部变量的差别。并给出一个有效使用了这三种变量的程序例子。

    从本质上讲,三者均属于局部作用域中的变量,其中,局部变量又分为普通(非静态)和静态局部变量。

    1、 形参的作用域为整个函数体,而普通(非静态)局部变量和静态局部变量的作用域为:从定义处到包含该变量定义的块的结束处;

    2、形参由调用函数时所传递的实参初始化;而普通(非静态)局部变量和静态局部变量通常用初始化式进行初始化,且均在程序执行流程第一次经过该对象的定义语句时进行初始化。静态局部变量的初始化在整个程序执行过程中只进行一次;

    3、形参和普通(非静态)局部变量均属于自动变量,在每次调用函数时创建,并在函数结束时撤销:而静态局部变量的生命期却跨越了函数的多次调用,它在创建后直到程序结束时才撤销。(一个是函数结束时撤销,一个是程序结束时撤销)

    int fac(int x){
      static int result=1;
      result*=x;
      return result;
    }
    int main(){
      int upmut;
      cout<<"please input :"<<endl;
      cin>>upmut;
      for(int i=1;i<=upmut;i++){
      cout<<fac(i)<<endl;//依次输出从1到upmut之间所有整数的阶乘
      }
      return 0;
    }
    int k;//全局变量,未初始化,默认初始化未0
    int main(){
      static int i;    //静态局部变量i ,未初始化,默认初始化未0
      int j;           //局部变量,不会默认初始化
      cout<<k<<endl;   //输出 0
      cout<<i<<endl;   //输出 0
      cout<<j<<endl;   //未初始化
      return 0;
    }
    展开全文
  • 学习总结:局部搜索

    万次阅读 2016-04-20 11:51:50
    局部搜索是能够无穷接近最优解的能力,而全局收敛能力是找到全局最优解所在大致位置的能力。局部搜索能力和全局搜索能力,缺一不可。向最优解的导向,对于任何智能算法的性能都是很重要的。   局部最优问题...


                            学习总结:局部搜索



    通常考察一个算法的性能通常用局部搜索能力和全局收敛能力这两个指标。局部搜索是指能够无穷接近最优解的能力,而全局收敛能力是指找到全局最优解所在大致位置的能力。局部搜索能力和全局搜索能力,缺一不可。向最优解的导向,对于任何智能算法的性能都是很重要的。 

        局部最优问题(或叫局部峰值\局部陷井):现实问题中,fD上往往有多个局部的极值点。一般的局部搜索算法一旦陷入局部极值点,算法就在该点处结束,这时得到的可能是一个糟糕的结果。解决的方法就,目标函数差的点,被选中的概率小。考虑归一化问题,使得邻域内所有点被选中的概率和为1总的来说,局部搜索的方法,就是依赖于对解空间进行按邻域搜索。

        起始点问题:一般的局部搜索算法是否能找到全局最优解,与初始点的位置有很大的依赖关系。解决的方法就是随机生成一些初始点,从每个初始点出发进行搜索,找到各自的最优解。再从这些最优解中选择一个最好的结果作为最终的结果。

        学习的重要性:
            1、直接用于无约束的实际问题;
            2、其基本思想和逻辑结构可以推广到约束问题;
            3、约束问题可以转化成无约束问题求解。

        方法分类:
            1、间接法:对简单问题,求解必要条件或充分条件;
            2、迭代算法:
                     零阶法:只需计算函数值 f(x) (直接法)
                     一阶法:需计算 ▽f(x)       (梯度法)
                     二阶法:需计算 ▽2f(x)      (梯度法)

        直接搜索法优点:计算不太复杂;易于实施与快速调试;所需的准备时间较少
    一、单纯形搜索法:

    1962年由Spendley, Hext和Himsworth提出,80年代得到证明。单纯形搜索法是一种无约束最优化的直接方法。单纯形法是求解非线性多元函数、无约束最小化问题的有效方法之一。在许多技术领域内,都取得了有效的成果。

    所谓的单纯形是指n维空间E^n中具有n+1个顶点的凸多面体。比如一维空间中的线段,二维空间中的三角形,三维空间中的四面体等,均为相应空间中的单纯形。单纯形搜索法与其它直接方法相比,基本思想有所不同,在这种方法中,给定维空间E^n中一个单纯形后,求出n+1个顶点上的函数值,确定出有最大函数值的点(称为最高点)和最小函数值的点(称为最低点),然后通过反射、扩展、压缩等方法(几种方法不一定同时使用)求出一个较好点,用它取代最高点,构成新的单纯形,或者通过向最低点收缩形成新的单纯形,用这样的方法逼近极小点。
        单纯形搜索法的基本思想是:先找出一个基本可行解,对它进行鉴别,看是否是最优解;若不是,则按照一定法则转换到另一改进的基本可行解,再鉴别;若仍不是,则再转换,按此重复进行。因基本可行解的个数有限,故经有限次转换必能得出问题的最优解。

    一般解题步骤可归纳如下:

    ①把线性规划问题的约束方程组表达成典范型方程组,找出基本可行解作为初始基本可行解。

    ②若基本可行解不存在,即约束条件有矛盾,则问题无解。

    ③若基本可行解存在,从初始基本可行解作为起点,根据最优性条件和可行性条件,引入非基变量取代某一基变量,找出目标函数值更优的另一基本可行解。

    ④按步骤3进行迭代,直到对应检验数满足最优性条件(这时目标函数值不能再改善),即得到问题的最优解。

    ⑤若迭代过程中发现问题的目标函数值无界,则终止迭代。 

    二、Powell共轭方向法(方向加速法)

    1964年由Powell提出,后经Zangwoll(1967年)和Brent(1973年)改进。该算法有效地利用了迭代过程中的历史信息,建立起能加速收敛的方向。

    理论基础:以二次对称函数为模型进行研究。

    在非线性目标函数中,最简单的是二次函数,故任何对一般函数有效的方法首先应对二次函数有效;在最优点附近,非线性函数可用一个二次函数作近似,故对二次函数使用良好的方法,通常对一般函数也有效;很多实际问题的目标函数是二次函数。

    设A是n×n阶对称正定矩阵,p(0), p(1)为两个n维向量,若 成立p(0)T A p(1) = 0,则称向量p(0)与p(1)为A共轭或A正交,称该两向量的方向为A共轭方向。 

    特点:Powell法本质上是以正定二次函数为背景,以共轭方向为基础的一种方法。不同于其他的直接法, Powell法有一套完整的理论体系,故其计算效率高于其他直接法。若每次迭代的前n 个搜索方向都线性无关时,则原始Powell法具有二次终止性 Powell法使用一维搜索,而不是跳跃的探测步。Powell法的搜索方向不一定为下降方向。

    不足:在原始Powell法中,必须保持每次迭代中前n个搜索方向线性无关,否则将永远得不到问题的最优解。

    为了避免出现搜索方向组线性相关的现象,Powell及其他人对原始Powell法进行修正:

    三、梯度法

        又名最速下降法求解无约束多元函数极值的数值方法,早在1847年就已由柯西(Cauchy))提出。它是导出其他更为实用、更为有效的优化方法的理论基础。因此,梯度法是无约束优化方法中最基本的方法之一。该方法选取搜索方向Pκ的出发点是:怎样选取Pk可使ƒ(X)下降得最快?或者说使ƒ(Xκ+λΡκ)-ƒ(Χκ)<0且不等式左式的绝对值尽量大。 

    目标:求出平稳点(满足Ñf(x)=0的x * )。对给定的解,按负梯度方向搜索其邻域解,若邻域中有更优的解(根据给定的评估函数评定),则移动至该邻域解,继续寻找,直至找不到为止。此时,就找到了局部最优解。方法非常简单,但是缺陷也很明显,即陷入到局部最优解之后无法跳出。

    注意:最速下降法的搜索路径呈直角锯齿形,相邻两个搜索方向是正交的。

    1、优点:计算简单,需记忆的容量小;对初始点要求低,稳定性高;远离极小点时收敛快,常作为其它方法的第一步。

    2、缺点:收敛速度较慢(线性或不高于线性),原因是最速下降方向只有在该点附近有意义。直线搜索可能会产生一些问题,可能会“之字型”地下降。尤其当目标函数等值面是很扁的椭圆、椭球或类似图形时,收敛更慢。

    四、Newton法

    由最速下降法可知,从全局角度来看,负梯度方向一般不是一个特别好的方向,有没有更好的方向

    基本思想:利用目标函数f(x)x(k)处的二阶Taylor展开式去近似目标函数,用二次函数的极小点去逼近目标函数的极小点。

       或  

    1、Newton法的最大优点是:Newton法是局部收敛的当初始点选得合适时收敛很快,具有二阶收敛速度,是目前算法中最快的一种。 对初始点要求高,一般要求初始点离极小点较近,否则不收敛。有时即使是收敛的,但因初始点离极大点或鞍点较近,会收敛于极大点或鞍点。

    2、Newton法的搜索方向-H (x)-1 g(x),称为Newton方向,是一个好方向,对二次函数此方向直指平稳点。如果H(x(k))是正定的,则H(x(k))-1必存在,从而算法是可行的,并且保证求得的平稳点是极小点。但在迭代过程中要求H(x(k))是正定的这一条件不一定能保证,因而它不一定是下降方向。一般在极小点附近的Hesse矩阵容易为正定的。所以基本Newton法在极小点附近才比较有效。

    五、共轭梯度法

    共轭梯度法最早是又Hestenes和Stiefle(1952)提出来的,用于解正定系数矩阵的线性方程组,在这个基础上,Fletcher和Reeves (1964)首先提出了解非线性最优化问题的共轭梯度法。由于共轭梯度法不需要矩阵存储,且有较快的收敛速度和二次终止性等优点,现在共轭梯度法已经广泛地应用与实际问题中。

    共轭梯度法(Conjugate Gradient)是介于最速下降法与牛顿法之间的一个方法,它仅需利用一阶导数信息,但克服了最速下降法收敛慢的缺点,又避免了牛顿法需要存储和计算Hesse矩阵并求逆的缺点,共轭梯度法不仅是解决大型线性方程组最有用的方法之一,也是解大型非线性最优化最有效的算法之一。 

    共轭梯度法是一个典型的共轭方向法,它的每一个搜索方向是互相共轭的,而这些搜索方向d仅仅是负梯度方向与上一次迭代的搜索方向的组合在各种优化算法中,共轭梯度法是非常重要的一种。其优点是所需存储量小,具有步收敛性,稳定性高,而且不需要任何外来参数。

    1、共轭梯度法不需要预先估计任何参数就可以计算,每次迭代所需的计算,主要是向量之间的运算,便于并行化。程序简单,对大规模问题很有吸引力。对一般函数为超线性收敛。

    2、共轭度法的收敛速度比最速下降法要快得多,同时也避免了要求海塞矩阵的计算收敛速度依赖于一维搜索的精确性及Hesse矩阵的特征值的分布。

        局部领域搜索是基于贪婪思想持续地在当前解的领域中进行搜索,虽然算法通用易实现,且容易理解,但其搜索性能完全依赖于领域结构和初解,尤其窥陷入局部极小而无法保证全局优化性。针对局部领域搜索,为了实现全局优化,可尝试的途径有:以可控性概率接受劣解来逃逸局部极小,如模拟退火算法;确定性的局部极小突跳策略,如禁忌策略;扩大领域搜索结构,如TSP的2opt扩展到k-opt;多点并行搜索,如进化计算;变结构领域搜索( Mladenovic et al,1997)等等。

    一、爬山法(Hill-Climbing)

    爬山算法是一种简单的贪心搜索算法,该算法每次从当前解的临近解空间中选择一个最优解作为当前解,直到达到一个局部最优解。爬山算法实现很简单,其主要缺点是会陷入局部最优解,而不一定能搜索到全局最优解。如下图所示:假设C点为当前解,爬山算法搜索到A点这个局部最优解就会停止搜索,因为在A点无论向那个方向小幅度移动都不能得到更优的解。

    爬山法是向值增加的方向持续移动到简单循环过程,算法在到达一个“峰顶”时终止,此时相邻状态中没有比该“峰顶”更高的值。爬山法不维护搜索树,当前节点只需要记录当前状态及其目标函数值;爬山法不会前瞻与当前状态不直接相邻的状态的值——“就像健忘的人在大雾中试图登顶珠峰一样”。爬山法从来不会“下山”,只会向值比当前节点好的方向搜索,因而肯定不完备,很容易停留在局部极值上
    function HillClimbing(problem) return 一个局部最优状态
        输入:problem
        局部变量:current, 一个节点
                  neighbor,一个节点
        current= MakeNode(Initial-State(problem));
        loop do
            neighbor= a highest-valued successor of current ;
            if VALUE[neighbor] <= VALUE[current] then return STATE[current];
            current= neighbor ;
        爬山法又称贪婪局部搜索,只是选择相邻状态中最好的一个。尽管贪婪是七宗罪之一,但是贪婪算法往往能够获得很好的效果。当然,爬山法会遇到以下问题:

    (1)局部极值

    (2)山脊:造成一系列的局部极值

    (3)高原:平坦的局部极值区域——解决办法:继续侧向移动
        随机爬山法:在上山移动中,随机选择下一步,选择的概率随着上山移动到陡峭程度而变化。

    首选爬山法:随机地生成后继节点直到生成一个优于当前节点的后继。

    随机重新开始的爬山法:“如果一开始没有成功,那么尝试,继续尝试”算法通过随机生成的初始状态来进行一系列的爬山法搜索,找到目标时停止搜索。该算法以概率1接近于完备:因为算法最终会生成一个目标状态作为初始状态。如果每次爬山搜索成功的概率为p,则需要重新开始搜索的期望次数为 1/p。

    二、模拟退火算法(Simulated Annealing)

    “模拟退火”算法是源于对热力学中退火过程的模拟,在某一给定初温下,通过缓慢下降温度参数,使算法能够在多项式时间内给出一个近似最优解。

        爬山法是完完全全的贪心法,每次都鼠目寸光的选择一个当前最优解,因此只能搜索到局部的最优值。模拟退火其实也是一种贪心算法,但是它的搜索过程引入了随机因素。模拟退火算法与爬山法类似,但是它没有选择最佳的移动,而是选择随机的移动。如果该移动使情况得到改善,那么接受该移动;否则,算法以某个概率接受该移动。因此有可能会跳出这个局部的最优解,达到全局的最优解。以上图为例,模拟退火算法在搜索到局部最优解A后,会以一定的概率接受到E的移动。也许经过几次这样的不是局部最优的移动后会到达D点,于是就跳出了局部最大值A。

    模拟退火的原理:我们将热力学的理论套用到统计学上,将搜寻空间内每一点想像成空气内的分子;分子的能量,就是它本身的动能;而搜寻空间内的每一点,也像空气分子一样带有“能量”,以表示该点对命题的合适程度。算法先以搜寻空间内一个任意点作起始:每一步先选择一个“邻居”,然后再计算从现有位置到达“邻居”的概率。可以证明,模拟退火算法所得解依概率收敛到全局最优解。

    当陷入局部最优之后,模拟退火算法要求概率根据算法进行过程中,逐步降低(逐渐降低才能趋向稳定)其跳出局部最优的概率,使其越来越趋于稳定。这一特性增加也同样存在缺陷,即对于全局最优解,也存在一定概率跳出,从而使得求解过程不稳定。

    随着邻域的范围的增大,跳出局部极小区域,最终进入全局极小区域的概率越来越大,但是代价是总的迭代次数增加。但是随着邻域范围的增大,会出现所谓的在极值附近来回”振荡”而无法落入极值点的现象。可以推测,随着邻域范围的进一步增大及其随机特性,模拟退火算法将退化到随机寻找极值并进行记录极值的算法。当然这种算法也存在问题,即对于某些情况下,也不易达到全局最优。例如,解空间中仅有两个局部最优,其中一个是全局最优,那么模拟退火似乎并不一定总能进入到全局最优解当中。

    Create initial solution S

    repeat

    for i=1 to iteration-length do

    Generate a random transition from S to Si

    If ( C(S) <= C(Si) ) then

    S=Si

    else if( exp(C(S)-C(Si))/kt > random[0,1) ) then

    S=Si

    Reduce Temperature t

    until ( no change in C(S) )

    C(S): Cost or Loss function of Solution S.

    1、在其他参数合适的情况下,初始解的位置与邻域结构是2个重要因素。

    2、初始解的位置与邻域结构的设计之间对于找到最优解的问题而言存在依赖关系。随着邻域的范围的增大,跳出局部极小区域,最终进入全局极小区域的概率越来越大,同时也可能会产生振荡,无法落入极值区域。

    3、模拟退火本质上也是一种 暴力搜索,只不过是利用随机的性质和局部极值区域连续(也取决于求解问题中邻域的结构)的特性避免了大量计算,进而在较短时间内从某种概率上逼近局部最优值和全局最优值。

    三、禁忌搜索(Tabu Search或Taboo Search,TS)

    禁忌搜索(Tabu Search或Taboo Search,简称TS)的思想最早由Glover(1986)提出,它是对局部领域搜索的一种扩展,是一种全局逐步寻优算法,是对人类智力过程的一种模拟。TS算法通过引入一个灵活的存储结构和相应的禁忌准则来避免迂回搜索,并通过藐视准则来赦免一些被禁忌的优良状态,进而保证多样化的有效探索以最终实现全局优化。相对于模拟退火和遗传算法,TS是又一种搜索特点不同的meta-heuristic算法。

    禁忌搜索是人工智能的一种体现,是局部领域搜索的一种扩展。禁忌搜索最重要的思想是标记对应已搜索的局部最优解的一些对象,并在进一步的迭代搜索中尽量避开这些对象(而不是绝对禁止循环),从而保证对不同的有效搜索途径的探索。禁忌搜索涉及到领域(neighborhood)、禁忌表(tabu list)、禁忌长度(tabu 1ength)、候选解(candidate)、藐视准则(candidate)等概念

    简单TS算法的基本思想描述如下:

    (1)给定算法参数,随机产生初始解x,置禁忌表为空。

    (2)判断算法终止条件是否满足?若是,则结束算法并输出优化结果;否则,继续以下步骤。

    (3)利用当前解的邻域函数产生其所有(或若干)邻域解,并从中确定若干候选解。

    (4)对候选解判断特赦准则是否满足?若成立,则用满足特赦准则的最佳状态y替代x成为新的当前解,即x=y,并用与y对应的禁忌对象替换最早进入禁忌表的禁忌对象,同时用y替换“best so far”状态,然后转步骤6;否则,继续以下步骤。

    (5)判断候选解对应的各对象的禁忌属性,选择候选解集中非禁忌对象对应的最佳状态为新的当前解,同时用与之对应的禁忌对象替换最早进入禁忌表的禁忌对象元素。

    (6)转步骤(2)。

    局部搜索,模拟退火,遗传算法,禁忌搜索的形象比喻:为了找出地球上最高的山,一群有志气的兔子们开始想办法。
        1、兔子朝着比现在高的地方跳去。他们找到了不远处的最高山峰。但是这座山不一定是珠穆朗玛峰。这就是局部搜索,它不能保证局部最优值就是全局最优值。
        2、兔子喝醉了。他随机地跳了很长时间。这期间,它可能走向高处,也可能踏入平地。但是,他渐渐清醒了并朝最高方向跳去。这就是模拟退火。
        3、兔子们吃了失忆药片,并被发射到太空,然后随机落到了地球上的某些地方。他们不知道自己的使命是什么。但是,如果你过几年就杀死一部分海拔低的兔子,多产的兔子们自己就会找到珠穆朗玛峰。这就是遗传算法。
        4、兔子们知道一个兔的力量是渺小的。他们互相转告着,哪里的山已经找过,并且找过的每一座山他们都留下一只兔子做记号。他们制定了下一步去哪里寻找的策略。这就是禁忌搜索。 

     



    http://blog.sciencenet.cn/blog-628137-497041.html    此文来自科学网邹锋博客,转载请注明出处。

                            学习总结:局部搜索



    通常考察一个算法的性能通常用局部搜索能力和全局收敛能力这两个指标。局部搜索是指能够无穷接近最优解的能力,而全局收敛能力是指找到全局最优解所在大致位置的能力。局部搜索能力和全局搜索能力,缺一不可。向最优解的导向,对于任何智能算法的性能都是很重要的。 

        局部最优问题(或叫局部峰值\局部陷井):现实问题中,fD上往往有多个局部的极值点。一般的局部搜索算法一旦陷入局部极值点,算法就在该点处结束,这时得到的可能是一个糟糕的结果。解决的方法就,目标函数差的点,被选中的概率小。考虑归一化问题,使得邻域内所有点被选中的概率和为1总的来说,局部搜索的方法,就是依赖于对解空间进行按邻域搜索。

        起始点问题:一般的局部搜索算法是否能找到全局最优解,与初始点的位置有很大的依赖关系。解决的方法就是随机生成一些初始点,从每个初始点出发进行搜索,找到各自的最优解。再从这些最优解中选择一个最好的结果作为最终的结果。

        学习的重要性:
            1、直接用于无约束的实际问题;
            2、其基本思想和逻辑结构可以推广到约束问题;
            3、约束问题可以转化成无约束问题求解。

        方法分类:
            1、间接法:对简单问题,求解必要条件或充分条件;
            2、迭代算法:
                     零阶法:只需计算函数值 f(x) (直接法)
                     一阶法:需计算 ▽f(x)       (梯度法)
                     二阶法:需计算 ▽2f(x)      (梯度法)

        直接搜索法优点:计算不太复杂;易于实施与快速调试;所需的准备时间较少
    一、单纯形搜索法:

    1962年由Spendley, Hext和Himsworth提出,80年代得到证明。单纯形搜索法是一种无约束最优化的直接方法。单纯形法是求解非线性多元函数、无约束最小化问题的有效方法之一。在许多技术领域内,都取得了有效的成果。

    所谓的单纯形是指n维空间E^n中具有n+1个顶点的凸多面体。比如一维空间中的线段,二维空间中的三角形,三维空间中的四面体等,均为相应空间中的单纯形。单纯形搜索法与其它直接方法相比,基本思想有所不同,在这种方法中,给定维空间E^n中一个单纯形后,求出n+1个顶点上的函数值,确定出有最大函数值的点(称为最高点)和最小函数值的点(称为最低点),然后通过反射、扩展、压缩等方法(几种方法不一定同时使用)求出一个较好点,用它取代最高点,构成新的单纯形,或者通过向最低点收缩形成新的单纯形,用这样的方法逼近极小点。
        单纯形搜索法的基本思想是:先找出一个基本可行解,对它进行鉴别,看是否是最优解;若不是,则按照一定法则转换到另一改进的基本可行解,再鉴别;若仍不是,则再转换,按此重复进行。因基本可行解的个数有限,故经有限次转换必能得出问题的最优解。

    一般解题步骤可归纳如下:

    ①把线性规划问题的约束方程组表达成典范型方程组,找出基本可行解作为初始基本可行解。

    ②若基本可行解不存在,即约束条件有矛盾,则问题无解。

    ③若基本可行解存在,从初始基本可行解作为起点,根据最优性条件和可行性条件,引入非基变量取代某一基变量,找出目标函数值更优的另一基本可行解。

    ④按步骤3进行迭代,直到对应检验数满足最优性条件(这时目标函数值不能再改善),即得到问题的最优解。

    ⑤若迭代过程中发现问题的目标函数值无界,则终止迭代。 

    二、Powell共轭方向法(方向加速法)

    1964年由Powell提出,后经Zangwoll(1967年)和Brent(1973年)改进。该算法有效地利用了迭代过程中的历史信息,建立起能加速收敛的方向。

    理论基础:以二次对称函数为模型进行研究。

    在非线性目标函数中,最简单的是二次函数,故任何对一般函数有效的方法首先应对二次函数有效;在最优点附近,非线性函数可用一个二次函数作近似,故对二次函数使用良好的方法,通常对一般函数也有效;很多实际问题的目标函数是二次函数。

    设A是n×n阶对称正定矩阵,p(0), p(1)为两个n维向量,若 成立p(0)T A p(1) = 0,则称向量p(0)与p(1)为A共轭或A正交,称该两向量的方向为A共轭方向。 

    特点:Powell法本质上是以正定二次函数为背景,以共轭方向为基础的一种方法。不同于其他的直接法, Powell法有一套完整的理论体系,故其计算效率高于其他直接法。若每次迭代的前n 个搜索方向都线性无关时,则原始Powell法具有二次终止性 Powell法使用一维搜索,而不是跳跃的探测步。Powell法的搜索方向不一定为下降方向。

    不足:在原始Powell法中,必须保持每次迭代中前n个搜索方向线性无关,否则将永远得不到问题的最优解。

    为了避免出现搜索方向组线性相关的现象,Powell及其他人对原始Powell法进行修正:

    三、梯度法

        又名最速下降法求解无约束多元函数极值的数值方法,早在1847年就已由柯西(Cauchy))提出。它是导出其他更为实用、更为有效的优化方法的理论基础。因此,梯度法是无约束优化方法中最基本的方法之一。该方法选取搜索方向Pκ的出发点是:怎样选取Pk可使ƒ(X)下降得最快?或者说使ƒ(Xκ+λΡκ)-ƒ(Χκ)<0且不等式左式的绝对值尽量大。 

    目标:求出平稳点(满足Ñf(x)=0的x * )。对给定的解,按负梯度方向搜索其邻域解,若邻域中有更优的解(根据给定的评估函数评定),则移动至该邻域解,继续寻找,直至找不到为止。此时,就找到了局部最优解。方法非常简单,但是缺陷也很明显,即陷入到局部最优解之后无法跳出。

    注意:最速下降法的搜索路径呈直角锯齿形,相邻两个搜索方向是正交的。

    1、优点:计算简单,需记忆的容量小;对初始点要求低,稳定性高;远离极小点时收敛快,常作为其它方法的第一步。

    2、缺点:收敛速度较慢(线性或不高于线性),原因是最速下降方向只有在该点附近有意义。直线搜索可能会产生一些问题,可能会“之字型”地下降。尤其当目标函数等值面是很扁的椭圆、椭球或类似图形时,收敛更慢。

    四、Newton法

    由最速下降法可知,从全局角度来看,负梯度方向一般不是一个特别好的方向,有没有更好的方向

    基本思想:利用目标函数f(x)x(k)处的二阶Taylor展开式去近似目标函数,用二次函数的极小点去逼近目标函数的极小点。

       或  

    1、Newton法的最大优点是:Newton法是局部收敛的当初始点选得合适时收敛很快,具有二阶收敛速度,是目前算法中最快的一种。 对初始点要求高,一般要求初始点离极小点较近,否则不收敛。有时即使是收敛的,但因初始点离极大点或鞍点较近,会收敛于极大点或鞍点。

    2、Newton法的搜索方向-H (x)-1 g(x),称为Newton方向,是一个好方向,对二次函数此方向直指平稳点。如果H(x(k))是正定的,则H(x(k))-1必存在,从而算法是可行的,并且保证求得的平稳点是极小点。但在迭代过程中要求H(x(k))是正定的这一条件不一定能保证,因而它不一定是下降方向。一般在极小点附近的Hesse矩阵容易为正定的。所以基本Newton法在极小点附近才比较有效。

    五、共轭梯度法

    共轭梯度法最早是又Hestenes和Stiefle(1952)提出来的,用于解正定系数矩阵的线性方程组,在这个基础上,Fletcher和Reeves (1964)首先提出了解非线性最优化问题的共轭梯度法。由于共轭梯度法不需要矩阵存储,且有较快的收敛速度和二次终止性等优点,现在共轭梯度法已经广泛地应用与实际问题中。

    共轭梯度法(Conjugate Gradient)是介于最速下降法与牛顿法之间的一个方法,它仅需利用一阶导数信息,但克服了最速下降法收敛慢的缺点,又避免了牛顿法需要存储和计算Hesse矩阵并求逆的缺点,共轭梯度法不仅是解决大型线性方程组最有用的方法之一,也是解大型非线性最优化最有效的算法之一。 

    共轭梯度法是一个典型的共轭方向法,它的每一个搜索方向是互相共轭的,而这些搜索方向d仅仅是负梯度方向与上一次迭代的搜索方向的组合在各种优化算法中,共轭梯度法是非常重要的一种。其优点是所需存储量小,具有步收敛性,稳定性高,而且不需要任何外来参数。

    1、共轭梯度法不需要预先估计任何参数就可以计算,每次迭代所需的计算,主要是向量之间的运算,便于并行化。程序简单,对大规模问题很有吸引力。对一般函数为超线性收敛。

    2、共轭度法的收敛速度比最速下降法要快得多,同时也避免了要求海塞矩阵的计算收敛速度依赖于一维搜索的精确性及Hesse矩阵的特征值的分布。

        局部领域搜索是基于贪婪思想持续地在当前解的领域中进行搜索,虽然算法通用易实现,且容易理解,但其搜索性能完全依赖于领域结构和初解,尤其窥陷入局部极小而无法保证全局优化性。针对局部领域搜索,为了实现全局优化,可尝试的途径有:以可控性概率接受劣解来逃逸局部极小,如模拟退火算法;确定性的局部极小突跳策略,如禁忌策略;扩大领域搜索结构,如TSP的2opt扩展到k-opt;多点并行搜索,如进化计算;变结构领域搜索( Mladenovic et al,1997)等等。

    一、爬山法(Hill-Climbing)

    爬山算法是一种简单的贪心搜索算法,该算法每次从当前解的临近解空间中选择一个最优解作为当前解,直到达到一个局部最优解。爬山算法实现很简单,其主要缺点是会陷入局部最优解,而不一定能搜索到全局最优解。如下图所示:假设C点为当前解,爬山算法搜索到A点这个局部最优解就会停止搜索,因为在A点无论向那个方向小幅度移动都不能得到更优的解。

    爬山法是向值增加的方向持续移动到简单循环过程,算法在到达一个“峰顶”时终止,此时相邻状态中没有比该“峰顶”更高的值。爬山法不维护搜索树,当前节点只需要记录当前状态及其目标函数值;爬山法不会前瞻与当前状态不直接相邻的状态的值——“就像健忘的人在大雾中试图登顶珠峰一样”。爬山法从来不会“下山”,只会向值比当前节点好的方向搜索,因而肯定不完备,很容易停留在局部极值上
    function HillClimbing(problem) return 一个局部最优状态
        输入:problem
        局部变量:current, 一个节点
                  neighbor,一个节点
        current= MakeNode(Initial-State(problem));
        loop do
            neighbor= a highest-valued successor of current ;
            if VALUE[neighbor] <= VALUE[current] then return STATE[current];
            current= neighbor ;
        爬山法又称贪婪局部搜索,只是选择相邻状态中最好的一个。尽管贪婪是七宗罪之一,但是贪婪算法往往能够获得很好的效果。当然,爬山法会遇到以下问题:

    (1)局部极值

    (2)山脊:造成一系列的局部极值

    (3)高原:平坦的局部极值区域——解决办法:继续侧向移动
        随机爬山法:在上山移动中,随机选择下一步,选择的概率随着上山移动到陡峭程度而变化。

    首选爬山法:随机地生成后继节点直到生成一个优于当前节点的后继。

    随机重新开始的爬山法:“如果一开始没有成功,那么尝试,继续尝试”算法通过随机生成的初始状态来进行一系列的爬山法搜索,找到目标时停止搜索。该算法以概率1接近于完备:因为算法最终会生成一个目标状态作为初始状态。如果每次爬山搜索成功的概率为p,则需要重新开始搜索的期望次数为 1/p。

    二、模拟退火算法(Simulated Annealing)

    “模拟退火”算法是源于对热力学中退火过程的模拟,在某一给定初温下,通过缓慢下降温度参数,使算法能够在多项式时间内给出一个近似最优解。

        爬山法是完完全全的贪心法,每次都鼠目寸光的选择一个当前最优解,因此只能搜索到局部的最优值。模拟退火其实也是一种贪心算法,但是它的搜索过程引入了随机因素。模拟退火算法与爬山法类似,但是它没有选择最佳的移动,而是选择随机的移动。如果该移动使情况得到改善,那么接受该移动;否则,算法以某个概率接受该移动。因此有可能会跳出这个局部的最优解,达到全局的最优解。以上图为例,模拟退火算法在搜索到局部最优解A后,会以一定的概率接受到E的移动。也许经过几次这样的不是局部最优的移动后会到达D点,于是就跳出了局部最大值A。

    模拟退火的原理:我们将热力学的理论套用到统计学上,将搜寻空间内每一点想像成空气内的分子;分子的能量,就是它本身的动能;而搜寻空间内的每一点,也像空气分子一样带有“能量”,以表示该点对命题的合适程度。算法先以搜寻空间内一个任意点作起始:每一步先选择一个“邻居”,然后再计算从现有位置到达“邻居”的概率。可以证明,模拟退火算法所得解依概率收敛到全局最优解。

    当陷入局部最优之后,模拟退火算法要求概率根据算法进行过程中,逐步降低(逐渐降低才能趋向稳定)其跳出局部最优的概率,使其越来越趋于稳定。这一特性增加也同样存在缺陷,即对于全局最优解,也存在一定概率跳出,从而使得求解过程不稳定。

    随着邻域的范围的增大,跳出局部极小区域,最终进入全局极小区域的概率越来越大,但是代价是总的迭代次数增加。但是随着邻域范围的增大,会出现所谓的在极值附近来回”振荡”而无法落入极值点的现象。可以推测,随着邻域范围的进一步增大及其随机特性,模拟退火算法将退化到随机寻找极值并进行记录极值的算法。当然这种算法也存在问题,即对于某些情况下,也不易达到全局最优。例如,解空间中仅有两个局部最优,其中一个是全局最优,那么模拟退火似乎并不一定总能进入到全局最优解当中。

    Create initial solution S

    repeat

    for i=1 to iteration-length do

    Generate a random transition from S to Si

    If ( C(S) <= C(Si) ) then

    S=Si

    else if( exp(C(S)-C(Si))/kt > random[0,1) ) then

    S=Si

    Reduce Temperature t

    until ( no change in C(S) )

    C(S): Cost or Loss function of Solution S.

    1、在其他参数合适的情况下,初始解的位置与邻域结构是2个重要因素。

    2、初始解的位置与邻域结构的设计之间对于找到最优解的问题而言存在依赖关系。随着邻域的范围的增大,跳出局部极小区域,最终进入全局极小区域的概率越来越大,同时也可能会产生振荡,无法落入极值区域。

    3、模拟退火本质上也是一种 暴力搜索,只不过是利用随机的性质和局部极值区域连续(也取决于求解问题中邻域的结构)的特性避免了大量计算,进而在较短时间内从某种概率上逼近局部最优值和全局最优值。

    三、禁忌搜索(Tabu Search或Taboo Search,TS)

    禁忌搜索(Tabu Search或Taboo Search,简称TS)的思想最早由Glover(1986)提出,它是对局部领域搜索的一种扩展,是一种全局逐步寻优算法,是对人类智力过程的一种模拟。TS算法通过引入一个灵活的存储结构和相应的禁忌准则来避免迂回搜索,并通过藐视准则来赦免一些被禁忌的优良状态,进而保证多样化的有效探索以最终实现全局优化。相对于模拟退火和遗传算法,TS是又一种搜索特点不同的meta-heuristic算法。

    禁忌搜索是人工智能的一种体现,是局部领域搜索的一种扩展。禁忌搜索最重要的思想是标记对应已搜索的局部最优解的一些对象,并在进一步的迭代搜索中尽量避开这些对象(而不是绝对禁止循环),从而保证对不同的有效搜索途径的探索。禁忌搜索涉及到领域(neighborhood)、禁忌表(tabu list)、禁忌长度(tabu 1ength)、候选解(candidate)、藐视准则(candidate)等概念

    简单TS算法的基本思想描述如下:

    (1)给定算法参数,随机产生初始解x,置禁忌表为空。

    (2)判断算法终止条件是否满足?若是,则结束算法并输出优化结果;否则,继续以下步骤。

    (3)利用当前解的邻域函数产生其所有(或若干)邻域解,并从中确定若干候选解。

    (4)对候选解判断特赦准则是否满足?若成立,则用满足特赦准则的最佳状态y替代x成为新的当前解,即x=y,并用与y对应的禁忌对象替换最早进入禁忌表的禁忌对象,同时用y替换“best so far”状态,然后转步骤6;否则,继续以下步骤。

    (5)判断候选解对应的各对象的禁忌属性,选择候选解集中非禁忌对象对应的最佳状态为新的当前解,同时用与之对应的禁忌对象替换最早进入禁忌表的禁忌对象元素。

    (6)转步骤(2)。

    局部搜索,模拟退火,遗传算法,禁忌搜索的形象比喻:为了找出地球上最高的山,一群有志气的兔子们开始想办法。
        1、兔子朝着比现在高的地方跳去。他们找到了不远处的最高山峰。但是这座山不一定是珠穆朗玛峰。这就是局部搜索,它不能保证局部最优值就是全局最优值。
        2、兔子喝醉了。他随机地跳了很长时间。这期间,它可能走向高处,也可能踏入平地。但是,他渐渐清醒了并朝最高方向跳去。这就是模拟退火。
        3、兔子们吃了失忆药片,并被发射到太空,然后随机落到了地球上的某些地方。他们不知道自己的使命是什么。但是,如果你过几年就杀死一部分海拔低的兔子,多产的兔子们自己就会找到珠穆朗玛峰。这就是遗传算法。
        4、兔子们知道一个兔的力量是渺小的。他们互相转告着,哪里的山已经找过,并且找过的每一座山他们都留下一只兔子做记号。他们制定了下一步去哪里寻找的策略。这就是禁忌搜索。 

     



    http://blog.sciencenet.cn/blog-628137-497041.html    此文来自科学网邹锋博客,转载请注明出处。
    展开全文
  • 局部特征

    2017-07-05 14:33:51
    局部特征 (local features),是近来研究的一大热点。大家都了解全局特征(global features),就是方差、颜色直方图等等。如果用户对整个图像的整体感兴趣,而不是前景本身感兴趣的话,全局特征用来描述总是比较...
  • 局部搜索 邻域搜索

    千次阅读 2020-01-19 20:25:53
    局部搜索是能够无穷接近最优解的能力,而全局收敛能力是找到全局最优解所在大致位置的能力。局部搜索能力和全局搜索能力,缺一不可。向最优解的导向,对于任何智能算法的性能都是很重要的。 局部最优问题(或叫...
  • 成员变量和局部变量

    2014-06-28 15:51:59
    在Java语言中,根据定义变量的位置的不同,可以将变量分为两大类:成员变量和局部变量。今天简单学习下成员变量和局部变量。 成员变量的是在类范围里...局部变量的是在方法里定义的变量。Java中变量的划分如图所
  • 形参、局部变量和静态局部变量的差别  从本质上说,三者均属于局部作用域中的变量,其中局部变量又可以分为普通(非静态)局部变量和静态局部变量。它们的差别: 作用域:形参的作用域为整个函数体;而普通(非...
  • 局部性原理的理解

    2021-03-08 23:07:54
    在计算机学科的概念中,局部性原理是一个常用的术语,处理器在访问某些数据时短时间内存在重复访问,某些数据或者位置访问的概率极大,大多数时间只访问局部的数据。主要可以分为时间局部性和空间局部性两种。 ...
  • 程序局部性原理感悟

    2014-12-30 18:24:00
     程序的局部性原理是程序在执行时呈现出局部性规律,即在一段时间内,整个程序的执行仅限于程序中的某一部分。相应地,执行所访问的存储空间也局限于某个内存区域。  局部性原理又表现为:时间局部性和空间局部...
  • 局部变量的是在方法里定义的变量。成员变量被分为类变量和实例变量两种。 定义成员变量时没有static修饰的就是实例变量,有static修饰的就是类变量。 其中类变量从该类的准备阶段开始存在,直到系统完全销毁这个...
  • 成员变量和局部变量同名 在同一个作用域内不允许定义同名的多个变量。   在一个方法内,可以定义和成员变量同名的局部变量或参数,此时成员变量被屏蔽。此时如果想要访问成员变量,可以通过 this 关键字来...
  • JAVA 面向对象 成员变量和局部变量

    万次阅读 多人点赞 2016-07-20 18:08:42
    本页面更新日期: 2016年07月20日前言 在 Java语言中, 根据定义变量位置的不同,可以将... 局部变量的是在方法里定义的变量. 下面我给出Java程序中的变量划分图: 成员变量被分为类变量和实例变量两种. 定义成员变
  • 1、定义不同:局部变量的是在函数内定义的变量,全局变量的是在函数外定义的变量。2、内存存储方式不同:全局变量存储在全局数据区中,局部变量存储在栈区。3. 生命期不同:全局变量的生命期和主程序一样,随...
  • 【笔记】局部特征

    2020-03-12 21:58:40
    全局特征是图像的整体属性,常见的全局特征包括颜色特征、纹理特征和形状特征,比如强度直方图等。由于是像素级的低层可视特征,因此,全局特征具有良好的不变性、计算简单、表示直观等特点,但特征维数高、计算量...
  • 操作系统的局部性原理

    千次阅读 2019-11-05 18:47:23
    时间局部性是如果程序中的某条指令一旦执行,则不久之后该指令可能再次被执行;如果某数据被访问,则不久之后该数据可能再次被访问。强调数据的重复访问。  利用时间局部性,缓存在现代程序系统中扮演...
  •  在Java中,成员变量的是在类内定义但又不存在方法中的变量,局部变量的是在方法里定义的变量。 1.1、成员变量、局部变量的划分  成员变量分为类变量和实例变量,定义成员变量时有static修饰的是类变量,...
  • 1、局部变量能否和全局变量重名?  答:能,局部会屏蔽全局。要用全局变量,需要使用 ":: "  局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器...
  • 程序的局部变量 全局变量 动态申请数据分别存储在什么地方? 量的类别: 根据作用域可分为全局变量和局部变量。 根据生存周期可分为静态存储方式和动态存储方式,具体地又分为自动的(auto)、静态的(static)、...
  • 程序的局部变量 全局变量 动态申请数据分别存储在什么地方? 量的类别: 根据作用域可分为全局变量和局部变量。 根据生存周期可分为静态存储方式和动态存储方式,具体地又分为自动的(auto)、静态的(static)、...
  • 是什么 效应局部化中的“效应“是...这是如果我们知道哪些地方受到影响,或许还有救。然而在大部分情况下,我们对此是一无所知,这时就得先花时间排查影响范围。、 但在效应局部化的情况下,我们需要阅读代码以及
  • 程序中的局部变量是编译时候分配地址的还是运行时分配的呢? [问题点数:40分] https://bbs.csdn.net/topics/350012472 borefo 结帖率 90% 程序中的局部变量是编译时候分配地址的还是运行时分配的呢? 按照我...
  • 上段函数中,即使已经运行了函数,但因为b是函数内的变量(即局部变量),其他地方无法调用,所以弹出的是undefined  全局变量:的是在整个javascript文件内都能调用的变量,当然,因为j
  • 比较全局变量、全局静态变量、局部变量、局部静态变量的区别,他们在编译完后存储位置在什么地方、初始化值在什么地方、内存什么时候分配、赋初值对这些变量有哪些影响等。要弄清楚这些问题,首先要弄清楚下面几个...
  • C++中不应该返回局部变量的地址

    千次阅读 2017-11-24 19:20:15
    在Effective C++中明确指出:不应该返回局部变量的引用,原因在于:局部变量会在函数返回后被销毁,因此被返回的引用就成为了”无所”的引用,程序会进入未知状态。如果比较理解函数局部变量的作用域和生命周期,...
  • 局部变量和全局变量的作用域

    千次阅读 2014-03-13 16:58:54
    java中的作用域:可访问变量的一段代码,在程序中不同的地方声明的变量具有不同的作用域,例如:局部变量,全局变量等。 局部变量:作用在它定义的方法或者方法里面的程序块变量。只能作用在方法里面或者方法里面...
  • 局部搜索与全局收敛

    千次阅读 2010-12-26 20:26:15
    局部搜索是能够无穷接近最优解的能力,而全局收敛能力是找到全局最优解所在大致位置的能力。 人同样不也有与这类似两种能力么?局部搜索能力对应人对于自己所遇到的事情刨根究底,从而精通的能力。举个例子,...
  • 全局变量和局部变量初始化问题

    千次阅读 2019-08-23 16:08:42
    这里需要分清一个事实,是变量系统都会默认给初始化,只不过全局变量默认初始化为0,而局部变量被初始化为随机数,这个随机数用不了,后面会验证。现在,我们要讨论的是程序猿或者程序媛需不需要给全局变量和局部...
  • 局部变量是在某个函数中声明的,只能在该函数中调用它,如果试图在超出范围的地方调用,程序就爆掉了 如果在函数内部定义与某个全局变量一样名称的局部变量,就可能会导致意外的效果,可能不是你期望的。因此不建议...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 145,760
精华内容 58,304
关键字:

局部是指哪些地方