精华内容
下载资源
问答
  • 为了改进算法的执行效率,提出BE-Apriori(binary encoded Apriori)算法,其充分利用了二进制数相比编程语言中各种数据结构在内存及运算速度上的优势,对事务记录进行二进制编码后加载到内存,然后利用等效的二进制...
  • 三位二进制普通编码器,使用三个与门组成,multisim10及以上版本可以正常打开仿真,是教材上的电路,可以直接仿真,方便大家学习。
  • 用matlab编写的经典二进制编码遗传算法算例,函数最大值并画图,附带注释。
  • 矩阵按键按下获取其二进制编码显示,同时获取其定义值的二进制编码显示,使用数码管,本例程只写了后一个,前一个直接从数组获取即可。
  • 人工智能作业,使用二进制编码的遗传进化算法解决TSP问题。
  • 遗传算法(GA)是最著名的进化...在本文中,我们将与您分享遗传算法的两个版本的MATLAB实现:二进制遗传算法和实数编码遗传算法。这些版本中的优化机制是相同的,并且仅在解决方案表示形式和遗传算子的意义上有所不同。
  • 很好的代码,供大家学习
  • 遗传算法的python实现(二进制编码),适用于python3.x环境,有详细的注释和两个给出的测试函数。
  • 主要介绍了JavaScript转换二进制编码为ASCII码的方法,涉及javascript编码转换的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
  • 计算机二进制编码

    2020-10-17 17:00:56
    二进制编码知识。


    从康拉德·楚泽在 Z-3 计算机中首先采用二进制计数以来,现代电子计算机都采用二进制编码。

    • 二进制是最基本的进位计数系统,只有 0 和 1,容易表达。
    • 二进制运算规则简单,可以通过逻辑和移位电路实现。

    二进制虽然表达简单,但其内容与数位却不方便识别。

    • 4 位二进制可以表示 1 位十六进制。
    • 有时会用十六进制数来替代二进制数,能够更方便识别二进制的内容与位数。
    • 必须注意:十六进制只是用于方便识别二进制数的内容与数位,计算机并不存在这些十六进制数。

    1. 整数的二进制编码

    针对数值信息(数学值)的编码,将数值本身值称作真值,将编码称为机器数。

    • 例如:将数字 8 编码为 1000,那么 8 称为真值,1000 称为机器数。
    • 计算机中定义了两种整数:无符号数和符号数。

    2. 无符号数编码

    无符号数,顾名思义是没有符号的数,编码时无需考虑符号位的编码。可以直接用真值的二进制形式作为机器数,即编码值。

    • 8 位二进制可以表达十进制中的 0 ~ 255,共 2 8 2^8 28 = 256 个数。
    • 无符号数进行计算时,如果运算结果超出取值范围,就会产生错误,这种情况称为溢出。
    • 例如:[200] + [100] = 11001000B + 01100100B = 00101100B = [44]
    • 计算结果应该为 300,超过了 8 位二进制数的取值范围 [0 ~ 255],从而得到错误的结果 44。
    • 无符号数编码的的加法/减法通过最高位的进位/借位来判断。

    3. 符号数编码

    符号数,编码时就要考虑符号编码了,不仅要表示真值的绝对值,还要表示真值的符号。
    针对符号数有四种编码方式:

    • 原码:最高位表示符号(正数用 0 表示,负数用 1 表示),其他位表示真值的绝对值。
    • 反码:正数的反码等价于原码,负数的反码就是将原码除符号位以外的其他绝对值部分按位取反。
    • 补码:正数的补码依旧等价于原码,负数的补码是将反码加1得到。
    • 移码:移码在补码的基础上增加了一个偏移量。

    3.1 原码

    早期计算机使用原码表示法,X 为真值,n 为二进制数的位数,原码定义如下:
    { [ X ] 原 = ∣ X ∣ , 0 ≤ X ≤ 2 n − 1 [ X ] 原 = 2 n − 1 + ∣ X ∣ , − 2 n − 1 ≤ X ≤ 0 \begin{cases} [X]_原=\mid X\mid,\quad\quad\quad\quad\quad\quad\quad 0\leq X \leq 2^{n-1} \\ [X]_原=2^{n-1}+\mid X \mid,\quad\quad-2^{n-1}\leq X \leq 0 \end{cases} {[X]=X,0X2n1[X]=2n1+X,2n1X0
    最高位表示符号(正数用 0 表示,负数用 1 表示),其他位表示真值的绝对值。

    • 例如 [1000 0100B],最高位符号位是 1,表示负数,绝对值部分[000 0100B] 表达 4,组合起来表达 -4。

    原码特点:

    • 乘除运算比较方便,单独处理符号与真值绝对值。
    • 加减运算比较复杂,首先处理符号,确定做加法还是减法,如果是减法,还需比较真值的大小,确定结果的符号。
    • 特殊数字 0 的原码有两个,判断是否为 0 需要分别判断 [+0] = [0000 0000B][-0] = 1000 0000B
    • 8 位二进制数可以表示 0000 0000B ~ 1111 1111B,即 -127 ~ +127,共 255 个数。

    3.2 反码

    一些老式计算机使用反码表示法,X 为真值,n 为二进制数的位数,反码定义如下:
    { [ X ] 反 = ∣ X ∣ , 0 ≤ X ≤ 2 n − 1 [ X ] 反 = 2 n − 1 − 1 − ∣ X ∣ , − 2 n − 1 ≤ X ≤ 0 \begin{cases} [X]_反=\mid X\mid,\quad\quad\quad\quad\quad\quad\quad\quad\quad 0\leq X \leq 2^{n-1} \\ [X]_反=2^{n-1}-1-\mid X \mid,\quad\quad-2^{n-1}\leq X \leq 0 \end{cases} {[X]=X,0X2n1[X]=2n11X,2n1X0
    正数的反码等价于原码, 负数的反码就是将原码除符号位以外的其他绝对值部分按位取反,故得名反码。

    • 例如:-3 的原码为[1000 0011B] ,它的反码为 [1111 1100B]

    反码特点:

    • 符号位一起参与加、减运算。
    • 加法进位需要送回到最低位再加(循环进位)。
    • 减法借位需要送回到最低位再减(循环借位)。
    • 减法可以转换为加法,简化了算数逻辑单元的设计。
    • 0 的反码也有两个,即 [0000 0000B][1000 0000B]
    • 8 位二进制数可以表示 0000 0000B ~ 1111 1111B,即 -127 ~ +127,共 255 个数。

    3.3 补码

    反码较好地解决了符号参与运算的问题,但循环进位/借位延长了计算时间,为了进一步简化,引入了补码。X 为真值,n 为二进制数的位数,补码的定义如下:
    { [ X ] 补 = ∣ X ∣ , 0 ≤ X ≤ 2 n − 1 [ X ] 补 = 2 n − 1 − ∣ X ∣ , − 2 n − 1 ≤ X ≤ 0 \begin{cases} [X]_补=\mid X\mid,\quad\quad\quad\quad\quad\quad\quad 0\leq X \leq 2^{n-1} \\ [X]_补=2^{n-1}-\mid X \mid,\quad\quad-2^{n-1}\leq X \leq 0 \end{cases} {[X]=X,0X2n1[X]=2n1X,2n1X0
    正数的补码依旧等价于原码,负数的补码是将反码加1。

    • 例如:-3 的原码是 [1000 0011B],反码为 [1111 1100B],补码为[1111 1101B]


      补码的特点:
    • 与反码一样,补码的符号位参与加/减运算,但回避了循环进位/借位。
    • 与反码一样,补码的减法运算可转化为加法运算。
    • 0的补码只有一种,即 ⌈ 00000000 B ⌋ \lceil00000000B\rfloor 00000000B,所以补码可以表示 -128~+127,其中 ⌈ 10000000 B ⌋ \lceil10000000B\rfloor 10000000B不再表示 0,而是表示 -128

    补码判断溢出使用双高异或判别法,如果最高位进位/借位与此高位进位/借位不同,则表示溢出。

    • 例如 120 + 16 时,
      0 1 1 1 1 0 0 0 B ( + 120 ) 补 + 0 0 0 1 0 0 0 0 B ( + 16 ) 补 = 1 0 0 0 1 0 0 0 B ( − 120 ) 补 \begin{array}{ccccccccc} &0&1&1&1&1&0&0&0B&(+120)_补\\ +&0&0&0&1&0&0&0&0B&(+16)_补\\ \hline =&1&0&0&0&1&0&0&0B&(-120)_补 \end{array} +=0011001001101010000000B0B0B(+120)(+16)(120)
    • 次高位产生进位,为 1 ,最高位没有产生进位,为 0, 1 ⨁ 0 = 1 1\bigoplus0=1 10=1,说明溢出。

    3.4 移码

    移码在补码的基础上增加了一个偏移量,X 为真值,n 为二进制数的位数,补码的定义如下:
    [ X ] 移 = 2 n − 1 + [ X ] 补 − 2 n − 1 ≤ X ≤ n n − 1 [X]_移=2^{n-1}+[X]_补\quad\quad -2^{n-1}\leq X \leq n^{n-1} [X]=2n1+[X]2n1Xnn1
    以 8 位二进制为例,则:.
    0 0 0 0 1 0 0 1 B ( [ + 9 ] 补 ) + 1 0 0 0 0 0 0 0 B ( 2 8 − 1 ) = 1 0 0 0 1 0 0 1 B ( [ + 9 ] 移 ) \begin{array}{cc} &0&0&0&0&1&0&0&1B&([+9]_补)\\\\ +&1&0&0&0&0&0&0&0B&(2^{8-1})\\\\ \hline\\ =&1&0&0&0&1&0&0&1B&([+9]_移) \end{array} +=0110000000001010000001B0B1B([+9])(281)([+9])
    1 0 0 0 1 0 0 1 B ( [ − 9 ] 原 ) 1 1 1 1 0 1 1 0 B ( [ − 9 ] 反 ) 1 1 1 1 0 1 1 1 B ( [ − 9 ] 补 ) + 1 0 0 0 0 0 0 0 B ( 2 8 − 1 ) = 0 1 1 1 0 1 1 1 B ( [ − 9 ] 移 ) \begin{array}{cc} &1&0&0&0&1&0&0&1B&([-9]_原) \\ &1&1&1&1&0&1&1&0B&([-9]_反) \\\\ &1&1&1&1&0&1&1&1B&([-9]_补)\\ +&1&0&0&0&0&0&0&0B&(2^{8-1})\\ \hline =&0&1&1&1&0&1&1&1B&([-9]_移) \end{array} +=111100110101101011011000001101011011B0B1B0B1B([9])([9])([9])(281)([9])


    4. 总结

    • 无符号数的编码为其二进制的表达形式。
    • 符号数的编码分为原码、反码、补码和移码。
      • 原码:最高位为符号位,取1表示负数,取0表示正数,其他位为真值的绝对值。
      • 反码:正数的反码就是原码,负数的反码为原码的符号位以外的其他位全部按位取反。
      • 补码:正数的补码就是原码,负数的补码为反码加1。
      • 移码:补码的基础上添加一个偏移量。
    • 8 位二进制的原码、反码、补码部分表:
    真值原码反码补码
    -128^^1000 0000
    -1271111 11111000 00001000 0001
    -1261111 11101000 00011000 0010
    -31000 00111111 11001111 1101
    -21000 00101111 11011111 1110
    -11000 00011111 11101111 1111
    -01000 00001111 11110000 0000
    +00000 00000000 00000000 0000
    +10000 00010000 00010000 0001
    +20000 00100000 00100000 0010
    +30000 00110000 00110000 0011
    1270111 11110111 11110111 1111
    展开全文
  • 对输入的二进制序列编码转换为:HDB3码
  • 二进制编码

    千次阅读 2019-11-29 18:12:41
    // 此工具方法用于按十六进制打印一个字节数组 ( 十六进制,参考《二进制篇》 ) public static void print(byte[] array, int off, int length) { for(int i=0; i; i++) { int index = off + i; if...

    在网络信道中,所有的数据都只能按照字节传输

     对所有的基本类型,均可以转成byte[]

    例如:

    booleanbyte[1]
    shortbyte[2]
    intbyte[4]
    floatbyte[4]
    doublebyte[8]
    longbyte[8]
    Stringbyte[N]

    ByteBuffer

    import java.nio.ByteBuffer,可译为字节缓冲区

    使用这个类,可以轻松完成二进制编解码

    ByteBuffer编码过程

    1、编译时,首先创建一个ByteBuffer对象,

    ByteBuffer bbuf = ByteBuffer.allocate(1000);

    2、然后把数据塞进去

    // 放入数据
    bbuf.putInt(1234);
    bbuf.putDouble(33.44);

    3、查看编码后的结果

    // 查看编码后的结果
    int size = bbuf.position();  // 已经编码的字节数
    byte[] array = bbuf.array(); // 取得ByteBuffer的内部数组

    package my;
    
    import java.nio.ByteBuffer;
    
    public class Test
    {
    	// 此工具方法用于按十六进制打印一个字节数组 ( 十六进制,参考《二进制篇》 )
    	public static void print(byte[] array, int off, int length)
    	{
    		for(int i=0; i<length; i++)
    		{
    			int index = off + i;
    			if(index >= array.length) break;
    			
    			if( i>0 && i%8 == 0)
    				System.out.printf("\n");
    			
    			System.out.printf("%02X ", array[index]);			
    		}
    		System.out.printf("\n");
    	}
    	
    
    	public static void main(String[] args)
    	{
    		// 注意:不支持 new ByteBuffer()来创建
    		ByteBuffer bbuf = ByteBuffer.allocate(1000);
    		
    		// 放入数据
    		bbuf.putInt(1234);
    		bbuf.putDouble(33.44);
    		
    		// 查看编码后的结果
    		int size = bbuf.position();  // 已经编码的字节数
    		byte[] array = bbuf.array(); // 取得ByteBuffer的内部数组
    		
    		print (array, 0, 12);
    		
    		System.out.println("exit");
    	}
    
    }
    

     

    展开全文
  • 各种传输二进制数据编码格式的Golang示例与比较。protobuf vs bson vs json vs xml
  • Matlab实现遗传算法(二进制编码

    热门讨论 2011-05-26 15:05:44
    使用Matlab实现二进制编码方案的遗传算法,算法分为初始化init.m、编码encoding、解码decoding、交叉crossover、变异mutation、选择selection以及适应度函数的计算。该文件为编码算法
  • 本文的遗传算法采用二进制编码求三元函数极值 所求函数为 要想使用遗传算法,首要任务是进行编码 传统的 GA 中, DNA 我们能用一串二进制来表示, 比如: DNA1 = [1, 1, 0, 1, 0, 0, 1] DNA2 = [1, 0, 1, 1, 0, 1, 1] ...

    想看实数编码编码的
    博客地址遗传算法求三元函数极值(python)-采用实数编码
    *

    遗传算法求三元函数极值(python)-采用二进制编码

    本文的遗传算法采用二进制编码求三元函数极值
    所求函数为
    在这里插入图片描述
    要想使用遗传算法,首要任务是进行编码

    传统的 GA 中, DNA 我们能用一串二进制来表示, 比如:
    DNA1 = [1, 1, 0, 1, 0, 0, 1]
    DNA2 = [1, 0, 1, 1, 0, 1, 1]
    这里,我们仍然使用二进制编码,但是如何与我们的问题对应起来呢?
    为什么会要用二进制编码, 我们之后在下面的内容中详细说明这样编码的好处. 但是长成这样的 DNA 并不好使用. 如果要将它解码, 我们可以将二进制转换成十进制, 比如二进制的 11 就是十进制的 3. 这种转换的步骤在程序中很好执行. 但是有时候我们会需要精确到小数, 其实也很简单, 只要再将十进制的数浓缩一下就好. 比如我有 1111 这么长的 DNA, 我们产生的十进制数范围是 [0, 15], 而我需要的范围是 [-1, 1], 我们就将 [0, 15] 缩放到 [-1, 1] 这个范围就好.
    我们知道二进制很容易转十进制,再区间压缩以下,这样一个DNA和一个解一一映射。

    def translateDNA(pop):
        return pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2**DNA_SIZE-1) * X_BOUND[1]
    

    例如,1 0 1 0 1 0 0 1 0 0 => (4+32+128+256)/(1024-1)*(5-0)=3.3
    上面针对的单变量的编码,求解单变量的函数极值
    其完整代码如下,这里照搬了别人的代码,后面我会给出引用地址,
    用它主要是参考,并修改为求解三元函数极值的代码
    单变量求函数极值:

    """
    Visualize Genetic Algorithm to find a maximum point in a function.
    可视化遗传算法去找到一个函数的最高点
    """
    import numpy as np
    import matplotlib.pyplot as plt
     
    DNA_SIZE = 10            # DNA length
    POP_SIZE = 100           # population size,种群中个体数目
    CROSS_RATE = 0.8         # mating probability (DNA crossover)0.8的概率进行交叉配对
    MUTATION_RATE = 0.003    # mutation probability,变异强度
    N_GENERATIONS = 200      #迭代次数
    X_BOUND = [0, 5]         # x upper and lower bounds,指定x的取值范围
     
     
    def F(x):
        return np.sin(10*x)*x + np.cos(2*x)*x     # to find the maximum of this function
     
     
    # find non-zero fitness for selection
    #我们都需要一个评估好坏的方程, 这个方程通常被称为 fitness适应度.
    #为了找到下面这个曲线当中的最高点. 那么这个 fitness 方程可以定义为高度, 越高的点, fitness 越高.
    def get_fitness(pred):
        return pred + 1e-3 - np.min(pred)#因为如果直接返回pred可能是负值,而我们在计算概率的时候不能为负值。
        #要进行处理,np.min表示取最小,为最大的负数,可以使全部只变成正的;1e-3为了让float进行相除防止小数点后的数被省略
     
     
    # convert binary DNA to decimal and normalize it to a range(0, 5)
    #对基因的翻译,如这里函数,x轴是实数,这里解释了如何将遗传01序列翻译成实数。用十进制二进制转换
    #pop (population)是一个储存二进制 DNA 的矩阵, 他的 shape 是这样 (pop_size, DNA_size)
    #这里DNA_SIZE,X_BOUND是超参数
    def translateDNA(pop):
        return pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2**DNA_SIZE-1) * X_BOUND[1]
        #dot()函数是矩阵乘,*则表示逐个元素相乘
    	#np.arange()函数返回一个有终点和起点的固定步长的排列
    	#pop.dot(2 ** np.arange(DNA_SIZE)[::-1])已经转换成十进制
    	#但是需要归一化到0~5,如有1111这么长的DNA,要产生的十进制数范围是[0, 15], 而所需范围是 [-1, 1],就将[0,15]缩放到[-1,1]这个范围
    	#a[::-1]相当于 a[-1:-len(a)-1:-1],也就是从最后一个元素到第一个元素复制一遍。所以你看到一个倒序
    	#np.arange(DNA_SIZE)[::-1]得到10,9,8,...,0
     
    #这里进行优胜劣汰的选择步骤
    #适者生存的 select() 很简单, 我们只要按照适应程度 fitness 来选 pop 中的 parent 就好. fitness 越大, 越有可能被选到.
    def select(pop, fitness):    # nature selection wrt pop's fitness
        idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True,p=fitness/fitness.sum())
    	#这里概率不能为负,所以pred要进行非负处理
    	#replace表示抽样后是否放回,这里为True表示有放回,则可能会出现相同的索引值
        # p 就是选它的比例,按比例来选择适应度高的,也会保留一些适应度低的,因为也可能后面产生更好的变异
        #np.random.choice表示从序列中取值  np.arange()函数返回一个有终点和起点的固定步长的排列
        return pop[idx]
     
    #繁衍,交叉父母的基因
    def crossover(parent, pop):     # mating process (genes crossover)
        if np.random.rand() < CROSS_RATE: #这里是0.8的概率父亲会选择一个母亲进行交叉配对
            i_ = np.random.randint(0, POP_SIZE, size=1)                           #select another individual from pop选择母亲索引一个
            cross_points = np.random.randint(0, 2, size=DNA_SIZE).astype(np.bool) #得到一行[01001100]也是01为了选择哪些点进行交叉;然后进行布尔化
            parent[cross_points] = pop[i_, cross_points]
    		#布尔型数组可以用于数组索引,布尔型数组长度必须跟被索引的轴长度一致
    		#生成布尔数组可以组合应用多个布尔条件,使用&(),|()之类的布尔算数运算符,python的关键字and和or在布尔型数组中无效
    		#parent[cross_points]即parent列表中取出cross_points为True地方的值&&&&&!!!!
    		#【母亲是pop的i_索引行DNA,选出母亲对应在cross_points为TRUE的地方的值】赋给【父亲DNA对应在cross_points选出为TRUE的地方的值】。
        return parent
     
    #繁衍,有变异的基因会出现
    #将某些 DNA 中的 0 变成 1, 1 变成 0
    def mutate(child):
        for point in range(DNA_SIZE):
            if np.random.rand() < MUTATION_RATE:
                child[point] = 1 if child[point] == 0 else 0
        return child
     
    #产生离散均匀分布的整数,若high不为None时,取[low,high)之间随机整数,否则取值[0,low)之间随机整数。
    pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE))   # initialize the pop DNA
    #pop = np.=random.randint(0,2,(1,DNA_SIZE).repeat(POP_SIZE,axis=0))这里是生成了一样的DNA,后面也可以随着变异变成不一样的
     
    #[[01001100],
    # [10111100],
    # ...]
    plt.ion()       # something about plotting开启图像交互模式
     
    x = np.linspace(*X_BOUND, 200)
    #linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
    #X_BOUND = [0, 5],要产生200个样本点
    #返回固定间隔的数据。他将返回num个等间距的样本,在区间[start,stop]中。其中,区间的结束端点可以被排除在外(用endpoint标识)
    plt.plot(x, F(x))
     
    for _ in range(N_GENERATIONS):
        F_values = F(translateDNA(pop))    # compute function value by extracting DNA传入到F函数
     
        # something about plotting
        if 'sca' in globals(): sca.remove()
        sca = plt.scatter(translateDNA(pop), F_values, s=200, lw=0, c='red', alpha=0.5); plt.pause(0.05)#plt.pause表示显示秒数
     
        # GA part (evolution)
        fitness = get_fitness(F_values) #计算适应度
        print("Most fitted DNA: ", pop[np.argmax(fitness), :])
        pop = select(pop, fitness)#这里选出了另外一种population
        pop_copy = pop.copy()# 备个份
        for parent in pop: #这里parent为遍历pop,一次为其中一行,而这里的pop是从原pop中按适应度概率有放回的选出了POP_SIZE行
            child = crossover(parent, pop_copy)#繁衍
            child = mutate(child) #进行变异
            parent[:] = child       # parent is replaced by its child# 宝宝变大人
     
    plt.ioff(); plt.show()
     
    #在使用matplotlib的过程中,不能像matlab一样同时开几个窗口进行比较,可以采用交互模式,但是放在脚本里运行一闪而过,图像并不停留
    #python可视化库matplotlib有两种显示模式:阻塞(block)模式&交互(interactive)模式
    #在交互模式下:plt.plot(x)或plt.imshow(x)是直接出图像,不需要plt.show()
    #如果在脚本中使用ion()命令开启了交互模式,没有使用ioff()关闭的话,则图像不会常留。防止这种情况,需要在plt.show()之前加上ioff()命令。
    #在阻塞模式下:打开一个窗口以后必须关掉才能打开下一个新的窗口。这种情况下,默认是不能像Matlab一样同时开很多窗口进行对比的
    #plt.plot(x)或plt.imshow(x)是直接出图像,需要plt.show()后才能显示图像
    
    

    关于三元函数代码的修改:
    我的想法是这样的,不知道对不对,不对的话,请大佬留言指出,首先要改的是种群pop产生的矩阵,我的代码是这样的:

     pop = np.random.randint(0,2, size=(POP_SIZE, DNA_SIZE*3)) #matrix (POP_SIZE, DNA_SIZE*3)
    

    第一个参数表示产生0-2范围的随机整数,不包括2

    为了说明方便,这里先假设POP_SIZE=10,DNA_SIZE=4,则DNA_SIZE*3=12,因为有三个变量x,y,z,每个变量占一个DNA_SIZE,则DNA总长度是12位,
    即[010011011010],
    则上面产生的种群矩阵为
    [[1 0 0 0 1 0 0 1 0 0 0 0]
    [0 1 1 1 1 1 1 1 1 0 1 1]
    [0 0 1 0 1 1 1 1 0 1 1 0]
    [1 1 0 0 1 1 1 0 1 1 0 0]
    [0 0 1 1 0 1 1 1 1 0 0 1]
    [1 0 0 1 0 1 1 0 1 0 0 0]
    [0 0 1 0 1 1 0 1 0 0 1 0]
    [1 1 1 1 0 1 1 0 0 1 1 0]
    [0 1 0 0 0 0 1 0 1 1 1 1]
    [1 1 1 1 1 1 1 0 1 1 0 0]]

    共10行,一行表示一个二进制编码表示的DNA,
    矩阵的行数为种群数目
    在上面的种群矩阵中,一行表示一个个体,而每个个体是有x,y,z三个基因片段所组成的,在这里
    取前DNA_SIZE=4列表示x
    所以x_pop为
    [[1 0 0 0]
    [0 1 1 1]
    [0 0 1 0]
    [1 1 0 0]
    [0 0 1 1]
    [1 0 0 1]
    [0 0 1 0]
    [1 1 1 1]
    [0 1 0 0]
    [1 1 1 1]],
    然后依次类推,中间4列表示y,最后4列表示z
    初始种群的个体即使都一样也无所谓,因为后面会通过交叉,配对等会变得不一样。
    在translateDNA这块修改如下,
    代码如下:

    def translateDNA(pop): #pop表示种群矩阵,一行表示一个二进制编码表示的DNA,矩阵的行数为种群数目
        x_pop = pop[:,0:DNA_SIZE]#取前DNA_SIZE个列表示x
        y_pop = pop[:,DNA_SIZE:DNA_SIZE*2]#取中间DNA_SIZE个列表示y
        z_pop = pop[:,DNA_SIZE*2:]#取后DNA_SIZE个列表示z
        #print(x_pop)
        #print(y_pop)
        #print(z_pop)
        #print("\n")
    
        '''pop:(POP_SIZE,DNA_SIZE)*(DNA_SIZE,1) --> (POP_SIZE,1)'''#二进制--->十进制
        x = x_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(X_BOUND[1]-X_BOUND[0])+X_BOUND[0]
        y = y_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(Y_BOUND[1]-Y_BOUND[0])+Y_BOUND[0]
        z = z_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(Z_BOUND[1]-Z_BOUND[0])+Z_BOUND[0]
        #print(x,z)
        return x,y,z
    

    有两种求解三元函数极值的代码,
    第一种是按照我自己的想法,在select操作中,关于概率的修改。
    下面是我的求解三元函数极值的完整代码:

    
    # x1*x2-x1*x2+x3
    import numpy as np
    import random
    
    
    DNA_SIZE = 24
    POP_SIZE = 100
    CROSSOVER_RATE = 0.8
    MUTATION_RATE = 0.015
    N_GENERATIONS = 100
    X_BOUND = [3.0,5.0]#x1
    Y_BOUND = [2.1,6.7]#x2
    Z_BOUND = [1.2,9.6]#x3
    
    
    def F(x, y,z):
       val=x*x-x*y+z
       #print(val)
       '''
       for index in range(len(val)):
          if val[index] <0.2:
             val[index]=0.2
             '''
       return val
    
    
    
    def get_fitness(pop): 
        x,y ,z= translateDNA(pop)
        pred = F(x, y,z)
        return pred
    
    def translateDNA(pop): #pop表示种群矩阵,一行表示一个二进制编码表示的DNA,矩阵的行数为种群数目
        x_pop = pop[:,0:DNA_SIZE]#取前DNA_SIZE个列表示x
        y_pop = pop[:,DNA_SIZE:DNA_SIZE*2] ##取中间DNA_SIZE个列表示y
        z_pop = pop[:,DNA_SIZE*2:]取后DNA_SIZE个列表示z
        #print(x_pop)
        #print(y_pop)
        #print(z_pop)
        #print("\n")
    
        '''pop:(POP_SIZE,DNA_SIZE)*(DNA_SIZE,1) --> (POP_SIZE,1)'''#二进制--->十进制
        x = x_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(X_BOUND[1]-X_BOUND[0])+X_BOUND[0]
        y = y_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(Y_BOUND[1]-Y_BOUND[0])+Y_BOUND[0]
        z = z_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(Z_BOUND[1]-Z_BOUND[0])+Z_BOUND[0]
        #print(x,z)
        return x,y,z
    
    
    def mutation(child, MUTATION_RATE=0.003):
    	if np.random.rand() < MUTATION_RATE: 				#以MUTATION_RATE的概率进行变异
    		mutate_point = np.random.randint(0, DNA_SIZE*3)	#随机产生一个实数,代表要变异基因的位置
    		child[mutate_point] = child[mutate_point]^1 	#将变异点的二进制为反转
    		
    def crossover_and_mutation(pop, CROSSOVER_RATE = 0.8):
    	new_pop = []
    	for father in pop:		#遍历种群中的每一个个体,将该个体作为父亲
    		child = father		#孩子先得到父亲的全部基因(这里我把一串二进制串的那些01称为基因)
    		if np.random.rand() < CROSSOVER_RATE:			#产生子代时不是必然发生交叉,而是以一定的概率发生交叉
    			mother = pop[np.random.randint(POP_SIZE)]	#再种群中选择另一个个体,并将该个体作为母亲
    			cross_points = np.random.randint(low=0, high=DNA_SIZE*3)	#随机产生交叉的点
    			child[cross_points:] = mother[cross_points:]		#孩子得到位于交叉点后的母亲的基因
    		mutation(child)	#每个后代有一定的机率发生变异
    		new_pop.append(child)
    
    	return new_pop
    
    
    
    def select(pop, fitness):    # nature selection wrt pop's fitness
        #idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True,
        fitnew = fitness
        for index in range(len(fitnew)):
            if fitnew[index] <0:
               fitnew[index]=0
          
        p=(fitnew)/(fitnew.sum())
    
        idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True,
                               p=p)
        #print(idx)
        return pop[idx]
    
    def print_info(pop):
    	fitness = get_fitness(pop)
    	max_fitness_index = np.argmax(fitness)
    	print("max_fitness:", fitness[max_fitness_index])
    	x,y,z = translateDNA(pop)
    	print("最优的基因型:", pop[max_fitness_index])
    	print("(x, y, z):", (x[max_fitness_index], y[max_fitness_index],z[max_fitness_index]))
    
    
    if __name__ == "__main__":
       pop = np.random.randint(0,2, size=(POP_SIZE, DNA_SIZE*3)) #matrix (POP_SIZE, DNA_SIZE)
       #print(pop)
       for _ in range(N_GENERATIONS):#迭代N代
          x,y,z = translateDNA(pop)
          pop = np.array(crossover_and_mutation(pop, CROSSOVER_RATE))
          fitness = get_fitness(pop)
          pop = select(pop, fitness) #选择生成新的种群
    
    	
       print_info(pop)
    
    
    

    第二种方法是按照网上的意思:关于函数值:因为如果直接返回pred可能是负值,而我们在计算概率的时候不能为负值。
    # 要进行处理,np.min表示取最小,为最大的负数,可以使全部只变成正的;1e-3为了让float进行相除防止小数点后的数被省略
    其完整代码如下:

    # x1*x2-x1*x2+x3
    import numpy as np
    import random
    
    DNA_SIZE = 24
    POP_SIZE = 100
    CROSSOVER_RATE = 0.8
    MUTATION_RATE = 0.015
    N_GENERATIONS = 100
    X_BOUND = [3.0, 5.0]  # x1
    Y_BOUND = [2.1, 6.7]  # x2
    Z_BOUND = [1.2, 9.6]  # x3
    
    
    def F(x, y, z):
        val = x * x - x * y + z
        return val
    
    
    def get_fitness(pop):
        x, y, z = translateDNA(pop)
        pred = F(x, y, z)
        return pred + 1e-3 - np.min(pred)  # 因为如果直接返回pred可能是负值,而我们在计算概率的时候不能为负值。
        # 要进行处理,np.min表示取最小,为最大的负数,可以使全部只变成正的;1e-3为了让float进行相除防止小数点后的数被省略
    
    
    def translateDNA(pop):  # pop表示种群矩阵,一行表示一个二进制编码表示的DNA,矩阵的行数为种群数目
        x_pop = pop[:, 0:DNA_SIZE]  # 取前DNA_SIZE个列表示x
        y_pop = pop[:, DNA_SIZE:DNA_SIZE * 2]  # 取中间DNA_SIZE个列表示y
        z_pop = pop[:, DNA_SIZE * 2:]  # 取后DNA_SIZE个列表示z
    
    
        '''pop:(POP_SIZE,DNA_SIZE)*(DNA_SIZE,1) --> (POP_SIZE,1)'''  # 二进制--->十进制
        x = x_pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2 ** DNA_SIZE - 1) * (X_BOUND[1] - X_BOUND[0]) + X_BOUND[0]
        y = y_pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2 ** DNA_SIZE - 1) * (Y_BOUND[1] - Y_BOUND[0]) + Y_BOUND[0]
        z = z_pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2 ** DNA_SIZE - 1) * (Z_BOUND[1] - Z_BOUND[0]) + Z_BOUND[0]
        # print(x,z)
        return x, y, z
    
    
    def mutation(child, MUTATION_RATE=0.003):
        if np.random.rand() < MUTATION_RATE:  # 以MUTATION_RATE的概率进行变异
            mutate_point = np.random.randint(0, DNA_SIZE * 3)  # 随机产生一个实数,代表要变异基因的位置
            child[mutate_point] = child[mutate_point] ^ 1  # 将变异点的二进制为反转
    
    
    def crossover_and_mutation(pop, CROSSOVER_RATE=0.8):
        new_pop = []
        for father in pop:  # 遍历种群中的每一个个体,将该个体作为父亲
            child = father  # 孩子先得到父亲的全部基因(这里我把一串二进制串的那些01称为基因)
            if np.random.rand() < CROSSOVER_RATE:  # 产生子代时不是必然发生交叉,而是以一定的概率发生交叉
                mother = pop[np.random.randint(POP_SIZE)]  # 再种群中选择另一个个体,并将该个体作为母亲
                cross_points = np.random.randint(low=0, high=DNA_SIZE * 3)  # 随机产生交叉的点
                child[cross_points:] = mother[cross_points:]  # 孩子得到位于交叉点后的母亲的基因
            mutation(child)  # 每个后代有一定的机率发生变异
            new_pop.append(child)
    
        return new_pop
    
    
    def select(pop, fitness):  # nature selection wrt pop's fitness
        idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True,
                               p=fitness/fitness.sum())
        # print(idx)
        return pop[idx]
    
    
    def print_info(pop):
        fitness = get_fitness(pop)
        max_fitness_index = np.argmax(fitness)
        # print("max_fitness:", fitness[max_fitness_index])
        x, y, z = translateDNA(pop)
        print("(x, y, z):", (x[max_fitness_index], y[max_fitness_index], z[max_fitness_index]))
        x=x[max_fitness_index]
        y=y[max_fitness_index]
        z=z[max_fitness_index]
        print("函数极值:", F(x,y,z))
    
    
    if __name__ == "__main__":
        pop = np.random.randint(0, 2, size=(POP_SIZE, DNA_SIZE * 3))  # matrix (POP_SIZE, DNA_SIZE)
        # print(pop)
        for _ in range(N_GENERATIONS):  # 迭代N代
            x, y, z = translateDNA(pop)
            pop = np.array(crossover_and_mutation(pop, CROSSOVER_RATE))
            fitness = get_fitness(pop)
            pop = select(pop, fitness)  # 选择生成新的种群
    
        print_info(pop)
    
    
    

    参考文献:
    https://blog.csdn.net/yyyxxxsss/article/details/82464736
    https://morvanzhou.github.io/tutorials/machine-learning/evolutionary-algorithm/2-01-genetic-algorithm/
    https://www.cnblogs.com/lfri/p/12240355.html
    https://blog.csdn.net/zxxxxxxy/article/details/105287743?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase

    展开全文
  • Binary-Coding-Based Ant Colony Optimization and Its Convergence 基于二进制编码的蚁群优化算法及其收敛性
  • 利用遗传算法函数f(x)=x+10sin(5x)+7cos(4x)f(x) =x+10sin(5x)+7cos(4x)的最大值

    问题描述

    求函数 f(x)=x+10sin(5x)+7cos(4x) 的最大值,其中 x 的取值范围是[0,10]

    该函数有多个局部极值

    f(x)=x+10sin(5x)+7cos(4x)


    Matlab遗传算法代码


    • 采用二进制编码
    • 轮盘赌选择法

    脚本

    初始化参数

    clear all;      %清除所有变量
    close all;      %清图
    clc;            %清屏
    NP=50;          %种群数量,一般取10~200,即染色体数目,将定义域划分50个(不等距)
    L=20;           %二进制位串长度,即染色体上基因数目,和计算要求的精度有关,如
                    %精10^-5,则2^19<10*10^5<2^20,至少需要20位
    Pc=0.8;         %交叉率,一般取0.25~1
    Pm=0.1;         %变异率,一般取0.001~0.1
    G=100;          %最大遗传代数,一般100~1000
    Xs=10;          %定义域上限
    Xx=0;           %定义域下限
    f=randi([0,1],NP,L);  %随机获得初始种群
    trace=zeros(1,G);     %预先分配内存

    解码

         for i=1:NP
            U=f(i,:);               %一条染色体
            m=0;
            for j=1:L
                m=U(j)*2^(j-1)+m;       %二进制转十进制的过程
            end
            x(i)=Xx+m*(Xs-Xx)/(2^L-1);  %将染色体解码在函数定义域
            Fit(i)=func1(x(i));         %适应度,即目标函数值   
        end

    求适应度最优

        maxFit=max(Fit);            %适应度最优
        minFit=min(Fit);            %适应度最差
        rr=find(Fit==maxFit);      
        %最大值在Fit数组中的位置,返回一个数组,因为可能有几个相同的最大值
        %这点要特别注意,所以下面不能直接用rr
        fBest=f(rr(1,1),:);         %最优适应度,有多个相同值时只取第一个
        xBest=x(rr(1,1));           %最优适应度对应的染色体
        Fit=(Fit-minFit)/(maxFit-minFit);   %归一化适应度值

    在本代挑选交配的父母染色体

    sum_Fit=sum(Fit);
        fitvalue=Fit./sum_Fit;      %可以看作概率密度f
        fitvalue=cumsum(fitvalue);  %可以看作概率累计F
        ms=sort(rand(NP,1));        %随机生成(0,1)的升序概率密度NP向量
        fiti=1;
        newi=1;
        %由ms可以看出这是一种随机的复制方式,但总趋势是将适应度比较大的遗传下去
            while newi <=NP   %父母双方以同样的方式挑选
            if (ms(newi)<fitvalue(fiti))
                nf(newi,:)=f(fiti,:);
                newi=newi+1;
            else
                fiti=fiti+1;
            end
        end

    随机交叉

     for i=1:2:NP
            p=rand;
            if p<Pc                     %控制交叉的染色体总数
                q=randi([0,1],1,L);     %随机生成要交叉的基因位置  
                for j=1:L
                    if q(j)==1
                        temp=nf(i+1,j);
                        nf(i+1,j)=nf(i,j);
                        nf(i,j)=temp;   %父母染色体在指定位置进行交叉
                    end
                end
            end
        end

    变异操作

        i=1;
        while i<=round(NP*Pm)       %控制变异染色体总数
            h=randi([1,NP],1,1);    %随机选取一个染色体
            for j=1:round(L*Pm)     %控制染色体上变异基因总数
                g=randi([1,L],1,1); %随机选取一个基因进行变异
                nf(h,g)=~nf(h,g);   %变异,即取反
            end
            i=i+1;
        end

    完整代码

    %%%%%标准遗传算法求函数极值%%%%
    %%%%%初始化参数%%%%%
    clear all;      %清除所有变量
    close all;      %清图
    clc;            %清屏
    NP=50;          %种群数量,一般取10~200,即染色体数目,将定义域划分50个(不等距)
    L=20;           %二进制位串长度,即染色体上基因数目,和计算要求的精度有关,如
                    %精度10^-5,则2^19<10*10^5<2^20,至少需要20Pc=0.8;         %交叉率,一般取0.25~1
    Pm=0.1;         %变异率,一般取0.001~0.1
    G=100;          %最大遗传代数,一般100~1000
    Xs=10;          %定义域上限
    Xx=0;           %定义域下限
    f=randi([0,1],NP,L);  %随机获得初始种群
    trace=zeros(1,G);     %预先分配内存
    %%%%%%%%遗传算法循环%%%%%%%%
    for k=1:G
      %%%%%%解码%%%%
        for i=1:NP
            U=f(i,:);               %一条染色体
            m=0;
            for j=1:L
                m=U(j)*2^(j-1)+m;       %二进制转十进制的过程
            end
            x(i)=Xx+m*(Xs-Xx)/(2^L-1);  %将染色体解码在函数定义域
            Fit(i)=func1(x(i));         %适应度,即目标函数值   
        end
        %%%%%%求适应度最优%%%%
        maxFit=max(Fit);            %目标函数最大值
        minFit=min(Fit);            %目标函数最小值
        rr=find(Fit==maxFit);      
        %最大值在Fit数组中的位置,返回一个数组,因为可能有几个相同的最大值
        %这点要特别注意,所以下面不能直接用rr
        fBest=f(rr(1,1),:);         %最优适应度,有多个相同值时只取第一个
        xBest=x(rr(1,1));           %最优适应度对应的染色体
        Fit=(Fit-minFit)/(maxFit-minFit);   %归一化适应度值
        %%%%%至此本代最优已筛选出来,下面开始为下一代作准备%%%%
        %%%%%基于轮盘赌的复制操作,在本代挑选出交配的父母双方%%%%
        sum_Fit=sum(Fit);
        fitvalue=Fit./sum_Fit;      %可以看作概率密度f
        fitvalue=cumsum(fitvalue);  %可以看作概率累计F
        ms=sort(rand(NP,1));        %随机生成(0,1)的有序概率密度NP大小向量
        fiti=1;
        newi=1;
        %由ms可以看出这是一种随机的复制方式,但总趋势是将适应度比较大的遗传下去
        while newi <=NP
            if (ms(newi)<fitvalue(fiti))
                nf(newi,:)=f(fiti,:);
                newi=newi+1;
            else
                fiti=fiti+1;
            end
        end
        %%%%%%%%基于概率的交叉操作%%%%%%%%
        for i=1:2:NP
            p=rand;
            if p<Pc                     %控制交叉的染色体总数
                q=randi([0,1],1,L);     %随机生成要交叉的基因位置  
                for j=1:L
                    if q(j)==1
                        temp=nf(i+1,j);
                        nf(i+1,j)=nf(i,j);
                        nf(i,j)=temp;   %两条相邻染色体在指定位置进行交叉
                    end
                end
            end
        end
        %%%%%%%%%基于概率的变异操作%%%%%%%%%%%%
        i=1;
        while i<=round(NP*Pm)       %控制变异染色体总数
            h=randi([1,NP],1,1);    %随机选取一个染色体进行变异
            for j=1:round(L*Pm)     %控制染色体上变异基因总数
                g=randi([1,L],1,1); %随机选取一个基因进行变异
                nf(h,g)=~nf(h,g);   %变异,即取反
            end
            i=i+1;
        end
        f=nf;                    %新一代种群                   
        f(1,:)=fBest;            %保留最优个体在新种群中
        trace(k)=maxFit;         %历代最优是应当由,即最大函数值
    end
    disp('最优解');
    disp(xBest);                 %最优个体,也就是最优解
    figure
    plot(trace)
    xlabel('迭代次数')
    ylabel('目标函数值')
    title('适应度进化曲线')

    函数

    function fit=func1(x)
    fit=x+10*sin(5*x)+7*cos(4*x);
    end

    计算结果

    函数最大值出现在 x=7.86 附近,约为24.86


    这里写图片描述

    展开全文
  • 本实验熟悉开发环境 Simulink 的使用,能够使用基本的逻辑门电路设计并实现 3-8二进制编码器。
  • 遗传算法之二进制编码

    万次阅读 热门讨论 2017-09-05 19:33:43
    遗传算法的基本步骤遗传算法 GA 的流程如图所示:Created with Raphaël 2.1.0编码把所需要选择的特征进行编号,每一个特征就是一个基因,一个解就是一串基因的组合。为了减少组合数量,在图像中进行分块,然后把每...
  • 杭电数字电路课程设计-实验四-二进制优先级编码器设计实验 内含包括代码,仿真,引脚配置全套文件,可直接打开工程
  • 编码、编码器和二进制编码

    千次阅读 2020-11-19 16:56:11
    将若干数码按一定顺序排列组成不同的代码,并赋予每个代码以一定的含义称为编码。如邮政编码,电话号码等...将2N个输入信号编成N位二进制代码的组合电路称为二进制编码器。 如下图为一般8线/3线编码器逻辑电路图: ...
  • 遗传算法的二进制编码

    千次阅读 2020-06-01 20:08:34
    假设我们要用遗传算法求解某个函数的最大值,x的取值范围是[-3.0,12.1],那么我们现在就是要从这个取值范围内...首先一个直观的想法是直接找到十进制对应的二进制,但是如果是那样做就涉及到有符号的二进制数了。 所
  • 字符二进制编码转换工具

    热门讨论 2011-01-05 22:03:49
    字符和的转换工具 字符和二进制的转换工具
  • 哈夫曼编码和二进制编码_案例

    千次阅读 多人点赞 2020-12-31 19:59:11
    哈夫曼编码优于二进制编码案例: 假设用于通信的电文仅由8个字母组成,字母在电文中出现的频率分别为0.07,0.19,0.02,0.06,0.32,0.03,0.21,0.10。试为这8个字母设计哈夫曼编码。使用0~7的二进制表示形式是另...
  • 遗传算法 二进制编码 matlab实现

    千次阅读 2020-03-31 18:17:09
    问题1:遗传算法第一步就是要解决编码问题,常用二进制编码,用过matlab的都知道有自带的十进制转换二进制的API,但是生成的char类型变量却不方便完成后续计算适应度、交叉、变异等操作; 问题2:常见实现编码方式为...
  • 使用它通过双二进制信令技术或修改后的双二进制信令技术对位序列进行编码。 双二进制信令是一种三级信令方案,它以受控方式使用符号间干扰,而不是试图消除它。
  • 主要介绍了C#对二进制数据进行base64编码的方法,涉及C#中Convert.ToBase64String用法技巧,需要的朋友可以参考下
  • 用遗传算法实现图像增强,采用的是二进制编码

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 411,343
精华内容 164,537
关键字:

二进制编码怎么求