精华内容
下载资源
问答
  • 代码优化的三个阶段
    千次阅读
    2014-06-24 14:08:23


    代码优化可以分为:

          (1)体系结构独立的优化

             (2)体系结构相关的优化(需要分析汇编代码)


    体系结构独立的优化主要是针对循环进行的,常用的有如下4种:


                 1)代码移动

                         把循环终止条件的计算由每次循环执行一次改为整个循环执行一次


                 2)循环展开

                         把循环体中一次只复制一个结构体改为二个结构体


                 3)减少过程调用(在循环中调用)

                         把循环体中的读取和设置结构体值的函数调用改为用数组下标


                4)消除不必要的存储器引用

                        在循环中引入中间变量

    更多相关内容
  • 代码优化三个阶段

    2011-11-23 00:02:49
    很久以前写的一个PPT,讨论了算法、流程及编码技巧三个层次的代码优化
  • 编译原理之代码优化

    万次阅读 多人点赞 2017-12-18 10:43:49
    编译原理出于代码编译的模块化组装考虑,一般会在语义分析的阶段生成平台无关的中间代码,经过中间代码级的代码优化,而后作为输入进入代码生成阶段,产生最终运行机器平台上的目标代码,再经过一次目标代码级别的...

    前面介绍完了词法分析、语法分析和语义分析,以及各阶段如何利用符号表来实现代码合理性确认以及代码地址拉链式回填等工作。编译原理出于代码编译的模块化组装考虑,一般会在语义分析的阶段生成平台无关的中间代码,经过中间代码级的代码优化,而后作为输入进入代码生成阶段,产生最终运行机器平台上的目标代码,再经过一次目标代码级别的代码优化(一般和具体机器的硬件结构高度耦合,复杂且不通用)。故而出于理解编译原理的角度考虑,代码优化一般都是以中间代码级代码优化手段作为研究对象。


    代码优化按照优化的代码块尺度分为:局部优化、循环优化和全局优化。即
    1. 局部优化:只有一个控制流入口、一个控制流出口的基本程序块上进行的优化;
    2. 循环优化:对循环中的代码进行的优化;
    3. 全局优化:在整个程序范围内进行的优化。

    1. 常见的代码优化手段

    常见的代码优化技术有:删除多余运算、合并已知量和复写传播,删除无用赋值等。采用转载自《编译原理》教材中关于这些优化技术的图例快速地展示下各优化技术的具体内容。

    针对目标代码:

    P := 0
    for I := 1 to 20 do 
        P := P + A[I]*B[I] 

    假设其翻译所得的中间代码如下



    1. 删除多余运算
    分析上图的中间代码,可以发现 (3)和式 (6)属于重复计算( 因为I并没有发生变化),故而式 (6)是多余的,完全可以采用 T4∶=T1代替。

    2. 代码外提
    减少循环中代码总数的一个重要办法是循环中不变的代码段外提。这种变换把循环不变运算,即结果独立于循环执行次数的表达式,提到循环的前面,使之只在循环外计算一次。针对改定的例子,显然数组A和 B的首地址在计算过程中并不改变,则作出的改动如下

    3. 强度削弱
    强度削弱的本质是把强度大的运算换算成强度小的运算,例如将乘法换成加法运算。针对上面的循环过程,每循环一次,I的值增加1T1的值与I保持线性关系,每次总是增加4。因此,可以把循环中计算T1值的乘法运算变换成在循环前进行一次乘法运算,而在循环中将其变换成加法运算。

    4. 变换循环控制条件
    IT1始终保持T1=4*I的线性关系,因此可以把四元式(12)的循环控制条件I≤20变换成T1≤80,这样整个程序的运行结果不变。这种变换称为变换循环控制条件。经过这一变换后,循环中I的值在循环后不会被引用,四元式(11)成为多余运算,可以从循环中删除。变换循环控制条件可以达到代码优化的目的。

    5. 合并已知量和复写传播
    四元式(3)计算4*I时,I必为1。即4*I的两个运算对象都是编码时的已知量,可在编译时计算出它的值,即四元式(3)可变为T1=4,这种变换称为合并已知量。

    四元式(6)T1的值复写到T4中,四元式(8)要引用T4的值,而从四元式(6)到四元式(8)之间未改变T4T1的值,则将四元式(8)改为T6∶=T5[T1],这种变换称为复写传播。

    6. 删除无用赋值
    (6)T4赋值,但T4未被引用;另外,(2)(11)对I赋值,但只有(11)引用I。所以,只要程序中其它地方不需要引用T4I,则(6)(2)(11)对程序的运行结果无任何作用。我们称之为无用赋值,无用赋值可以从程序中删除。至此,我们可以得到删减后简洁的代码

    2. 基本块内的局部优化

    1. 基本块的划分
      入口语句的定义如下:
      ① 程序的第一个语句;或者,
      ② 条件转移语句或无条件转移语句的转移目标语句;
      ③ 紧跟在条件转移语句后面的语句。
    有了入口语句的概念之后,就可以给出划分中间代码(四元式程序)为基本块的算法,
      其步骤如下:
      ① 求出四元式程序中各个基本块的入口语句。
      ② 对每一入口语句,构造其所属的基本块。它是由该入口语句到下一入口语句(不包括下一入口语句),或到一转移语句(包括该转移语句),或到一停语句(包括该停语句)之间的语句序列组成的。
      ③ 凡未被纳入某一基本块的语句、都是程序中控制流程无法到达的语句,因而也是不会被执行到的语句,可以把它们删除。

    2. 基本块的优化手段
    由于基本块内的逻辑清晰,故而要做的优化手段都是较为直接浅层次的。目前基本块内的常见的块内优化手段有:
    1. 删除公共子表达式
    2. 删除无用代码
    3. 重新命名临时变量 (一般是用来应对创建过多临时变量的,如t2 := t1 + 3如果后续并没有对t1的引用,则可以t1 := t1 + 3来节省一个临时变量的创建
    4. 交换语句顺序
    5. 在结果不变的前提下,更换代数操作(x∶=y**2是需要根据**运算符重载指数函数的,这是挺耗时的操作,故而可以用强度更低的x∶=y*y来代替
    根据以上原则,对如下代码进行优化

    t1 := 4 - 2
    t2 := t1 / 2 
    t3 := a * t2
    t4 := t3 * t1
    t5 := b + t4
     c := t5 * t5

    给出优化的终版代码

       t1 := a + a
       t1 := b + t1
        c := t1 * t1

    显然代码优化的工作不能像上面那样的人工一步步确认和遍历,显然必然要将这些优化工作公理化。而一般到涉及到数据流和控制流简化的这种阶段,都是到了图论一展身手的时候。

    3. DAG(无环路有向图)应用于基本块的优化工作
    在DAG图中,通过节点间的连线和层次关系来表示表示式或运算的归属关系:
    ① 图的叶结点,即无后继的结点,以一标识符(变量名)或常数作为标记,表示这个结点代表该变量或常数的值。如果叶结点用来代表某变量A的地址,则用addr(A)作为这个结点的标记。
    ② 图的内部结点,即有后继的结点,以一运算符作为标记,表示这个结点代表应用该运算符对其后继结点所代表的值进行运算的结果。
    (注:该部分内容转载自教材《编译原理》第11章DAG无环路有向图应用于代码优化)

    DAG构建的流程如下

    对基本块的每一四元式,依次执行:
      1. 如果NODE(B)无定义,则构造一标记为B的叶结点并定义NODE(B)为这个结点;
      如果当前四元式是0型,则记NODE(B)的值为n,转4。
      如果当前四元式是1型,则转2.(1)。
      如果当前四元式是2型,则:(Ⅰ)如果NODE(C)无定义,则构造一标记为C的叶结点并定义NODE(C)为这个结点,(Ⅱ)转2.(2)。
      2. 
      (1) 如果NODE(B)是标记为常数的叶结点,则转2.(3),否则转3.(1)。
      (2) 如果NODE(B)和NODE(C)都是标记为常数的叶结点,则转2.(4),否则转3.(2)。
      (3) 执行op B(即合并已知量),令得到的新常数为P。如果NODE(B)是处理当前四元式时 新构造出来的结点,则删除它。如果NODE(P)无定义,则构造一用P做标记的叶结点n。置NODE(P)=n,转4.。
      (4) 执行B op C(即合并已知量),令得到的新常数为P。如果NODE(B)或NODE(C)是处理当前四元式时新构造出来的结点,则删除它。如果NODE(P)无定义,则构造一用P做标记的叶结点n。置NODE(P)=n,转4.。
      3.
      (1) 检查DAG中是否已有一结点,其唯一后继为NODE(B),且标记为op(即找公共子表达式)。如果没有,则构造该结点n,否则就把已有的结点作为它的结点并设该结点为n,转4.。
      (2) 检查DAG中是否已有一结点,其左后继为NODE(B),右后继为NODE(C),且标记为op(即找公共子表达式)。如果没有,则构造该结点n,否则就把已有的结点作为它的结点并设该结点为n。转4.。
      4.
      如果NODE(A)无定义,则把A附加在结点n上并令NODE(A)=n;否则先把A从NODE(A)结点上的附加标识符集中删除(注意,如果NODE(A)是叶结点,则其标记A不删除),把A附加到新结点n上并令NODE(A)=n。转处理下一四元式。

    说着很复杂,下面看一个案例

    (1) T0∶=3.14
    (2) T1∶=2 * T0
    (3) T2∶=R + r
    (4) A∶=T1 * T2
    (5) B∶=A
    (6) T3∶=2 * T0
    (7) T4∶=R + r
    (8) T5∶=T3 * T4
    (9) T6∶=R - r
    (10) B∶=T5 * T6

    其DAG图的构建过程如下

    通过DAG图可以发现诸多的优化信息,如重复定义、无用定义等,则根据上图的DAG图可以构建最后的优化代码序列

      (1) S1∶=R+r
      (2) A∶=6.28*S1
      (3) S2∶=R-r
      (4) B∶=A *S2

    3.循环优化

    根据上面基本块的定义,我们将诸多基本块组装在一起,构建成程序循环图,如针对下面这个例子

      (1) read x
      (2) read y
      (3) r∶=x mod y
      (4) if r=0 goto (8)
      (5) x∶=y
      (6) y∶=r
      (7) goto (3)
      (8) write y
      (9) halt

    则按照上面基本块的划分,可以分成四个部分,四个部分的控制流分析可知可以得到一个循环图

    循环块最主要的特点是只有一个数据流和控制流入口,而出口可能有多个。循环优化的主要手段有:循环次数无关性代码外提、删除归纳变量和运算强度削弱。关于这三种手段的理解可以借助此前的描述进行类比,基本并无太多差异。

    展开全文
  • 欲提高源程序的运行速度,需要经过几个阶段优化: 用户对源程序进行优化(和编译器无关,与coder设计的算法有关) 编译器前端对中间代码进行优化 编译器后端对目标代码进行优化 两个编译器必须等价,编译的结果...

    一、代码优化的阶段

    欲提高源程序的运行速度,需要经过几个阶段的优化:

    1. 用户对源程序进行优化(和编译器无关,与coder设计的算法有关)
    2. 编译器前端对中间代码进行优化
    3. 编译器后端对目标代码进行优化

    两个编译器必须等价,编译的结果必须是正确的,即使有99.99%的可能性是不正确的,但是效率很好也不行,正确性是根本。

    二、中间代码优化的分类

    从优化的种类来看,中间代码的优化可有如下分类:

    1. 局部优化

    循环上的优化(所有优化方法效果最好的)
    1. 循环不变体外提
    循环中不因循环而改变的部分可以提到循环的外部
    2. 削减运算强度
    在一些循环上的计算转换成另一种计算方式实现,比如b=a*2 -> b=a+a
    基本块的优化(按照某些规则划分成基本块)
    1. 常表达式节省
    2. 公共子表达式节省

    1. 全局优化

    全局数据流分析,从而使优化的效果更好
    考虑基本块里如何优化,已经得到的值和变量的表,全局得到更多的信息进行分析。
    在局部优化的基础上进行全局优化才有更大的提高,否则直接进行全局优化的提升效果不明显。

    三、常见的编译优化的种类

    1. 数学上的优化

    情况一:(主要是在生成中间代码的时候会产生)

    (-,a,0,t1) (*,a,1,t2)
    //这种a+0,和a*1的没有太大意义的运算,这样的四元式可以删除
    //正常写普通的代码一般不会出现这种情况
    //但是在一些不明显的地方,比如计算数组中的元素a[i]时,用【i-(数组下界)】xsize
    //数组下界为0的时候和size=1的时候都会产生上面的四元式
    //可直接换但是还要将运算结果进行处理
    

    情况二:

    2*a->a+a
    a^2->a*a
    

    原则上说,可以不计算的直接删去其四元式,直接写出结果;高运算强度的可以转化成低运算强度的。

    2. 表达式短路问题

    在这里插入图片描述
    如果在计算一个表达式的时候可以不用将整个表达式的值都计算出来就可以确定表达式的结果,在这种情况下,后面的计算可以省略。
    或运算:如果计算出第一个表达式的结果是1可以直接返回 true
    与运算:如果计算出第一个表达式的结果是0可以直接返回false

    3. 常表达式的节省

    • 计算过程中有一个表达式是33.14,这个实际上是两个常数,他的结果我是可以计算出来的,这样我们在编译的过程中把33.14算出来,在目标程序的进行中就不用进行计算了。
    • 通过编译程序将可以计算出的结果直接计算出来然后将相应位置替换成计算出的结果。
    • 把有关工作交给编译程序进行可以提高生成的目标程序的运行效率,编译程序可以稍微慢些的工作,因为最后看的还是生成的目标程序的运行效率。

    4. 公共子表达式节省(消除重复操作)

    在这里插入图片描述

    • 所谓公共子表达式即两个子表达式的计算结果是一样的,不需要重复的进行计算,第一次计算出来之后,后面的计算可以利用前面的计算结果。例如前面有表达式ab,后面又有表达式也是ab,而且在第二个表达式和第一个表达式中间,a和b的值没有被改变过,那第二个a*b表达式实际上是可以不用计算的,只需要把前面的计算结果拿过来就可以达到计算的目的。
    • 这种情况在下标变量的计算中体现的非常明显,比方说a[i][j]和a[i][k],下标变量的计算先计算a[i]的地址然后计算j,然后计算a[i][j]的地址,a[i][k]也是一样先计算a[i]的地址在根据k计算a[i][k]的地址,所以前面关于a[i]的计算结果是完全一样的。这样就可以不用重复计算,利用前面的结果达到计算目的。

    5. 循环不变量式外提

    在这里插入图片描述
    循环不变式外提,在循环中,如果有一个表达式的值在循环中不会改变,就需要把它提到循环体的外面去。比方说有一个双重循环1-100和1-100,那么整个两重循环计算下来就是1万次,比方说里面有一个ab的表达式,在循环过程中ab的值如果不改变,那他就重复计算了9999次,假如把ab提到循环体的外面只需要计算1次,在循环里只需要用到它的计算结果。所以这样的表达式在循环体里面是不变的,我们要把他提到循环体的外面,从而提高我们的执行效率,这种效率的提高是最高的。特别是计算量很大的情况下,比方说有多重循环,这种循环不不变式外提可以大大提高程序的执行效率,这种提高的效率大概可以提高十几倍甚至是几十倍,串式程序的并行处理很大的一个研究重点,都是放在循环的并行计算上,比方说1~1000次的循环把它分成段,在不同的处理机上进行执行,从而提高程序的执行效率

    6. 削减程序的运算强度

    在这里插入图片描述
    削减程序的运算强度。这个也通常是针对循环的,一种特例的情形,比方说在程序设计语言中通常来说,一般的程序循环有三种方式分别是:
    1)for循环(有的语言中也称作是步长式的循环),循环形式是for i=e1 to e2 ;step e3{} 也就是说它的执行是i开始获取一个循环初值e1,然后每次循环i都加上e3的值,一直当i大于e2就结束循环,比方说for1=1to 100;step 1,就是1-100步长是1执行100次。
    2)while循环,“当型循环”()
    3)直到型循环 do until ~~的形式

    7. 寄存器优化

    在这里插入图片描述

    生成目标代码的时候一定是和目标机相关的,对于目标机来说提供多少个寄存器,比方说提供了8个,当目标程序真正执行的时候,这8个寄存器是如何被分配的,这是一个问题。简单的说假如说寄存器有空闲的时候,分配方案比较简单,空闲的就分配,这个没问题,什么时候会有问题呢?
    有这样几种情况:
    要用寄存器的时候,是否有空闲的寄存器,如果没有空闲的怎么办?需要剥夺一个寄存器,如何来剥夺?类似的还有内存和外存进行淘汰页的算法是类似的,只不过这个是在更高一级的层面上,寄存器和内存间的变换。这是寄存器分配优化

    8. 消除无用语句,消除冗余代码

    在这里插入图片描述

    消除无用语句,消除冗余代码,假如一个条件语句,if e s1 else s2 ,如果表达式E的值是一个true,那么s2是不可能用到了,所以这个命令就可以删掉了,这个命令也直接可以用s1来替换掉,当然这是一种特殊的情形,产生冗余代码实际上也是这么产生的

    9. 中间变量优化

    在这里插入图片描述

    中间变量的优化,生成中间代码的时候会产生大量的临时变量,大量的临时变量的特点一般都是产生之后使用一次就会不再用了,如果是说有一些临时变量和另外一些临时变量之间没有交集的话,不需要为每一个临时变量都分配独立的存储单元。最简单的方式,把产生临时变量一直到使用临时变量这个区域比方说把它定义为临时变量的活动区,假如两个临时变量的活动区不相交,实际上他们可以共用同一个存储单元,那么这种优化实际上就是临时变量的存储空间上的优化

    10. 目标代码优化

    在这里插入图片描述

    是目标代码的优化,可以通过确定目标代码来减少目标程序的指令个数来提高目标程序的执行效率,比方说有一个变量的值在寄存器里,运算出来的中间结果在寄存器里,假如直接让他参与运算之后,就不用往内存中存了,什么时候需要存,什么时候不存,什么时候需要把它放在寄存器里,这就是需要对目标程序进行的一种优化,根据使用情况来进行。

    11. 全局优化

    在这里插入图片描述
    总而言之这种优化还有很多,比方说全局的数据流分析和全局的优化,因为前面考虑实现的时候由于优化的技术可能比较复杂,都是在局部区做的,比方说一个基本块上做的,要想做到全局的需要对全局的程序做全局的数据流分析,这样的话可能就更复杂了,如果没有特殊需求,一般来说是不做这样的优化的:
    第一个原因就是编译代价太大,因为要做各种各样的分析,导致编译代价很大。
    第二就是提高的效率也并不是十分的明显。

    如果说没有特殊的需求,前面做的局部优化已经能达到想要的效果,全局优化就不用做了,特殊需求的时候才想办法处理。

    ⚠️优化中要注意的一个问题就是优化是在保证正确的情况下进行的,任何一个程序的优化也不能做到最优,而是在一定程度上来提高程序的执行效率。所以优化的过程一定是在保证程序正确的前提下来进行的。

    四、基本块

    (一)基本块的定义

    在这里插入图片描述

    • 基本快:是一个命令的序列,每一条命令都是按照顺序来执行的,进入基本块只能从第一条命令进入,退出基本块只能从最后一条命令退出,也就是说基本块是一个整体,要执行的话就全都执行从头到尾的顺序执行,这样一个特性对于程序进行分析或者是对中间代码进行分析有什么好处呢?对程序基本块中变量的性质是可判定的,假如不是基本块的话,x=10;L y=x+1;如果说只能从x=10这条语句顺序执行的话,y=x+1,这个x就是一个已知的,就是10,y就是11.但是假如说它有另外一个入口,其他地方有一个goto L,就不能判断x的值是不是10,因为外面有一个转移,比方说x=1; goto L x的值就不一定是10了,不是基本块的话程序的性质就不太好判断
    • 假如说是一个基本块都是顺序往下执行的话,那么每一个变量的值是怎么获取的、怎么传播出来的,就可以判断出来,这对我们的处理就非常有意义。因此在基本块上做优化使得问题变的相对简单了。

    (二)基本块的划分原则

    在这里插入图片描述

    1. 进入一个程序,(整个程序的第一条)四元式就是一个基本块的入口四元式;
    2. 遇到一个转移性的四元式,这条转移性的四元式是结束了一个基本块,它的后续四元式就可以作为下一个基本块的第一条四元式;
    3. 遇到一个定位性的四元式或者是标号性的四元式,就结束一个基本块,并作为下一个基本块的第一条四元式;
    4. 那么遇到一些函数的结束标示,就结束当前的四元式。例如p=&x; *p=5; y=x+x; 因为p是间接取址的,所以要结束这个标准块,否则也还是不知道如何来判断。

    在这里插入图片描述
    比方说goto还有(then t1,- ,-)目标程序运行到这的时候要判断t1是真是假,如果是假的话就要跳过t1,所以一定是要产生一个跳转指令的,还比如else这种,也就是说s1执行完一定要产生一个跳转指令跳过s2。
    在这里插入图片描述
    比方说循环指令中的while四元式,当循环体循环结束之后要产生一个跳转指令,要转移到前面重复计算的表达式的位置,假如没有这样一个四元式, 就没有办法确定转移到什么地方。这样的四元式就起到一个定位型四元式,还有比方说endif等等。还有对间接变量的赋值,也表示一个基本块的结束,这是基本块划分的原则,总的来说最关键的两点就是遇到转移型四元式和定位型四元式的开始
    在这里插入图片描述
    在这里插入图片描述

    五、常表达式节省

    在编译过程中能够计算出值的表达式,就在中间代码这级给它计算一个结果,这样就不需要在目标程序执行的时候进行计算了。
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    1. 首先构造一个表,即变量的值表,表中元素是一个二元组,表项左部是一个变量名或者是一个临时变量,右边是已知它的值是什么,就填到这里。
    2. 以后的优化算法也就比较简单,通常来说是这样做的:进入到一个基本快的时候把这个表清空,遇到一个运算型的四元式,比方说有算符 a b t1,首先看一下a和b是不是常量,如果是常量当然可以进行计算,就把t1填到表里。如果是变量的话,就要去表中查一下有没有变量对应的值,如果有值,就把这个变量用值来替换然后来看看可不可以进行计算,能计算就进行计算,不能计算替换完了之后,值就放到四元式中。
    3. 如果遇到一个赋值型四元式,比方说b=a,就要到表里去查a有没有值,如果a是已知的,就把b填到表里,把a的值取出来填给b。按照这样顺序进行计算,能够算出常量值的四元式就被节省掉了。这里要注意,运算型的四元式实际上第一步,严格来说,用常量值替代运算符,比方说3*3.14 t1,就算出t1的结果,以后用到t1的时候就从表里取t1的值就可以了
    4. 中间可以夹杂着用常量定值表对原有四元式进行替换,如果四元式都变成常量的就删除,否则就留着

    在这里插入图片描述
    在这里插入图片描述

    展开全文
  •  工作流程一般分为三个阶段。 阶段一:直接按照需要用C语言实现功能。在实际的DSP应用中,许多算法都是非常复杂,直接用汇编代码编写,虽然优化效率很高,可是实现的难度却很大,所以一般都采用先用C语言来实现,...
  • 优化算法(Snake Optimizer,SO)由Fatma A. Hashim和Abdelazim G. Hussien于2022年提出,该算模拟了蛇的觅食和繁殖行为。该算法是思路新颖,快速高效。 二、算法原理 雄性蛇和雌性蛇之间交配的发生受到某些因素...

    一、算法简介

    蛇优化算法(Snake Optimizer,SO)由Fatma A. Hashim和Abdelazim G. Hussien于2022年提出,该算法思路新颖,快速高效,模拟了蛇的觅食和繁殖行为。

    在这里插入图片描述

    二、算法原理

    雄性蛇和雌性蛇之间交配的发生受到某些因素的影响。蛇在春末和初夏交配,那时温度低。但交配过程不仅取决于温度,还取决于食物的充足性。如果温带低,食物充足;雄性蛇会互相争斗,以吸引雌性的注意力。雌性有权决定是否交配。如果发生交配,雌性开始在巢穴或洞穴中产卵,一旦卵出现,它就会离开。
    在这里插入图片描述

    蛇优化算法受蛇交配行为的启发,如果温度低且食物充足,则会发生交配,否则蛇只会寻找食物或吃掉剩余的食物。蛇优化算法分为两个阶段即全局探索或局部开发。探索取决于环境因素,即寒冷的地方和食物,在这种情况下,蛇只在周围寻找食物。对于开发,此阶段包括许多过渡阶段,以使全局更有效率。在食物可用但温度高的情况下,蛇只会专注于吃可用的食物。如果食物可用并且该区域寒冷,则会导致交配过程的发生;交配过程进行战斗模式或交配模式。在战斗模式中,每个雄性都会为获得最好的雌性而战,每个雌性都会尝试选择最好的雄性。在交配模式下,每对配对之间发生交配与食物数量的可用性有关。如果交配过程发生,则雌性产卵并将其孵化成新的蛇。SO将群体分成两个相等的群体即雄性和雌性。

    2.1全局搜索(无食物)

    如果Q<0.25,蛇通过选择任何随机位置来搜索食物,并更新它们的位置。

    雄性蛇位置更新:
    在这里插入图片描述

    雌性蛇位置更新:
    在这里插入图片描述

    2.2局部搜索(有食物)

    如果Q>0.25,且温度>0.6,则蛇只会向食物移动:
    在这里插入图片描述

    如果Q>0.25,且温度<0.6,则蛇将处于战斗模式或交配模式

    2.2.1战斗模式

    雄性蛇位置更新:
    在这里插入图片描述

    雌雄蛇位置更新:
    在这里插入图片描述

    2.2.2交配模式

    雄性蛇位置更新:

    在这里插入图片描述

    雌雄蛇位置更新:
    在这里插入图片描述

    三、算法流程

    在这里插入图片描述

    四、数值实验

    将蛇优化算法的优良策略与多目标优化思想融合,形成多目标蛇优化算法(Multiple Objective Snake Optimizer,MOSO),为了验证所提的MOSO的有效性,将其在46个多目标测试函数(ZDT1、ZDT2、ZDT3、ZDT4、ZDT6、DTLZ1-DTLZ7、WFG1-WFG10、UF1-UF10、CF1-CF10、Kursawe、Poloni、Viennet2、Viennet3)以及1个工程应用(盘式制动器设计)上实验。

    4.1函数测试

    部分测试函数求解结果:

    ZDT1:

    在这里插入图片描述

    ZDT2:

    在这里插入图片描述

    ZDT3:

    在这里插入图片描述

    ZDT4:

    在这里插入图片描述

    ZDT6:

    在这里插入图片描述

    DTLZ1:

    在这里插入图片描述

    DTLZ2:

    在这里插入图片描述

    DTLZ3:

    在这里插入图片描述

    DTLZ4:

    在这里插入图片描述

    DTLZ5:

    在这里插入图片描述

    DTLZ6:

    在这里插入图片描述

    DTLZ7:

    在这里插入图片描述

    4.2工程应用

    盘式制动器设计
    在这里插入图片描述

    MOSO求解结果:

    在这里插入图片描述

    4.3评价指标

    在这里插入图片描述
    MOSO思路新颖,算法及其高效,在多目标函数测试集上优势显著,大力推荐。

    五、源代码见评论区或私聊博主

    展开全文
  • 三个点的白屏(左侧): 下载代码包的阶段 没有三个点的白屏(中间): 业务代码注入和渲染的阶段 加载中(右边): 业务代码中异步请求数据 总的来说,小程序呈现到用户面前,实际上经历了下面两个阶段: 运行...
  • YOLOV5 的小目标检测网络结构优化方法汇总(附代码)

    万次阅读 多人点赞 2022-01-08 00:33:07
    点击上方“3D视觉工坊”,选择“星标”干货第一时间送达作者丨南山来源丨AI约读社YOLOv5是一种非常受欢迎的单阶段目标检测,以其性能和速度著称,其结构清晰灵活。虽然 yolov5是一...
  • Web前端开发学习3:SEO代码优化

    千次阅读 2015-10-31 18:28:17
    代码优化概述  关于代码优化的知识是纯理论的知识,学习的很枯燥。在学到CSS时,不免遇到CSS+div进行代码优化的知 识,因此在网上看了一些关于这方面的知识,简单的整合一下,梳理自己所了解的代码优化问题。  ...
  • Java class类文件和类加载器详解以及Java代码优化
  • 从计算机程序出现的第一天起,对效率的追求就是程序天生的坚定信仰,这过程犹如一场没有终点,永不停歇的F1方程式竞赛,程序员试车手,技术平台则是在赛道上飞驰的赛车。 文章目录早期(编译期)优化概述Javac...
  • Java代码优化提点

    万次阅读 多人点赞 2013-10-30 11:04:16
     代码优化是指对程序代码进行等价(指不改变程序的运行结果)变换。程序代码可以是中间代码,也可以是目标代码。等价的含义是使得变换后的代码运行结果与变换前代码运行结果相同。优化的含义是最终生成的目标代码...
  • 天鹰优化器AO及MATLAB代码编程1 算法原理简介1.1 扩大探索阶段1.2 缩小探索阶段1.3 扩大开发阶段1.4 缩小开发阶段2 算法流程3 MATLAB代码结果 1 算法原理简介 天鹰优化器(Aquila Optimizer, AO)是一种新型智能优化...
  • 前言今日头条 iOS 端从 2016 年起就关注到了安装包大小的问题,并启动了包大小优化。2017 年,我们将当时的经验发表为技术文章 《干货|今日头条iOS端安装包大小优化—思路与实践...
  • 白鲨优化算法(White Shark Optimizer,WSO)由Malik Braik等人于2022年提出,该算法受大白鲨导航和觅食时具有的非凡听觉和嗅觉启发。该算法思路新颖,策略高效。 大白鲨体呈纺锤型,躯干较粗壮。头一般长。尾基上...
  • 关于代码评审(CodeReview)那些不得不说的事儿

    千次阅读 多人点赞 2022-05-07 20:00:20
    在一成熟的团队中,CodeReview是整个研发流程中不可或缺的一步,而那些即将走向成熟的团队可能对CodeReview有很多的误解和问题,也不清楚CodeReview该如何去做,本文笔者将结合自己的经验和知识,谈谈我对Code...
  • 初探一0代码开发—iVX平台

    千次阅读 多人点赞 2020-12-06 18:54:39
    五、aPaaS,iPaaS(Cloud-based integration) & PaaS 这三个概念,就不在这里细说了,都是云计算领域的概念“平台即服务”的延伸,iVX符合这个定义。 六、无代码编程/可逆计算 参考这两篇知乎文章: ...
  • 程序编译与代码优化

    千次阅读 2016-05-31 15:20:23
    一早期(编译期)优化 1概述 Java语言的“编译期”是一段“不确定”的操作过程,因为它可能是指一前端编译器(其实叫“编译器的前端”更准确一些)把*.java文件转变成*.class文件的过程;也可能是指虚拟机的...
  • 智能优化算法:蝗虫优化算法-附代码

    千次阅读 热门讨论 2020-07-30 17:20:04
    智能算法:蝗虫优化算法-附代码 摘要:蝗虫算法( Grasshopper Optimization Algorithm,GOA ) 是 由 Saremi 等[1]于2017 年提出的一种元启发式仿生优化算法,具有较高的搜索效率和较快的收敛速度,且算法本身特殊的...
  • 鹈鹕优化算法(Pelican Optimization Algorithm,POA)由Pavel Trojovský和Mohammad Dehghani 于2022年提出,该算法模拟了鹈鹕在狩猎过程中的自然行为。 鹈鹕很大,喙很长,喉咙里有一大袋子,用来捕捉和吞咽猎物。...
  • 智能优化算法:海鸥优化算法-附代码

    万次阅读 多人点赞 2020-07-23 14:24:01
    2019智能算法:海鸥优化算法-附代码 摘要:本文简单介绍智能优化算法-海鸥优化算法 1.原理 海鸥是遍布全球的海鸟,海鸥种类繁多且大小和身长各不相同。 海鸥是杂食动物,吃昆虫、鱼、爬行动物、两栖动物和蚯蚓等。 ...
  • 算法原理1.1 蜂群的初始化1.2 雇佣蜂阶段1.3 跟随蜂阶段1.4 探索蜂阶段2.算法流程3.算法结果4.参考文献5.MATLAB代码 摘要:人工蜂群算法(artificial bee colony,ABC)是由土耳其学者Karaboga 于 2005 年提出,它是...
  • java优化代码常见套路

    万次阅读 多人点赞 2019-12-28 11:32:03
    程序员的痛点(烂代码) ...首先说一最重要的优化原则:代码优化是你觉得你代码很繁琐、阅读性很差的时候一定要马上优化,立刻马上,不管你现在有多忙,每天优化才叫重构,每年优化那叫重写 这原则为什么重...
  • 在公司有一需求需要将前端传过来的10张照片,后端接收过来进行处理以后压缩成一压缩包通过网络流传输出去。之前没有接触过用Java压缩文件的,所以就...未优化压缩文件的代码如下: private static String ZI...
  • 快速排序算法详细教程及其优化,C语言代码

    万次阅读 多人点赞 2019-04-19 22:37:27
    快速算法 简介: 快速排序是基于分治技术的重要排序算法,排序算法按照元素的值对它们进行划分。...显然,建立了一划分以后,A[s]A[s]A[s]已经位于它在有序数组中的最终结果,接下来我们可以继续对A[s]A[...
  • 一次代码评审,差点过不了试用期!

    万次阅读 多人点赞 2020-09-15 09:46:38
    作者:小傅哥 ... 沉淀、分享、成长,让自己和他人都能有所收获!???? ...好的代码往往也很好看 代码是给机器运行的,但...PRD评审、研发设计评审、代码开发、代码评审以及中间一些列的提交物,直到测试完成,上线验证,开量
  • 代码执行流水之循环展开优化

    千次阅读 2020-05-12 17:57:07
     对指令序列进行优化调度,以减少空转周期  浮点加法部件采用流水指令流出时钟 第种情况:  对指令序列进行优化调度,以减少空转周期  浮点运算部件不采用流水 循环展开和指令调度时要注意以下几方面:...
  • 一些代码优化的方法

    千次阅读 2016-01-13 14:30:59
    当然不是,C++层次一样可以作代码优化,其中有些常常是意想不到的。在C++层次进行优化,比在汇编层次优化具有更好的移植性,应该是优化中的首选做法。 1 确定浮点型变量和表达式是 float 型 为了让编译器产生更好...
  • 技术的三个阶段

    2020-03-18 15:43:47
    三个阶段优化 当我们能将功能都实现了,也借鉴了许多别人的东西时,重心就应放在思考如何优化代码上,考虑代码的可读性、安全性、可扩展性以及服务器的优化。这时候建议大家看一些设计模式、编程思想、网站安全...
  • 我们是如何优化英雄联盟的代码

    千次阅读 2017-05-08 11:44:42
    优化已有的代码库,我们采用了三个基本步骤:鉴别、理解和迭代。 步骤一鉴别 在开始之前,我们首先需要确认哪些代码需要进行优化。即使有些代码看起来明显性能较差,但是由于其对整体性能影响极小,优化...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 252,104
精华内容 100,841
热门标签
关键字:

代码优化的三个阶段