想看实数编码编码的
博客地址遗传算法求三元函数极值(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 pltDNA_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轴是实数,这里解释了如何将遗传0、1序列翻译成实数。用十进制二进制转换
#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 fitnessidx = 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]也是0、1为了选择哪些点进行交叉;然后进行布尔化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 0return 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 plottingif '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)#这里选出了另外一种populationpop_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个列表示xy_pop = pop[:,DNA_SIZE:DNA_SIZE*2]#取中间DNA_SIZE个列表示yz_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 randomDNA_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]#x3def 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 valdef get_fitness(pop): x,y ,z= translateDNA(pop)pred = F(x, y,z)return preddef translateDNA(pop): #pop表示种群矩阵,一行表示一个二进制编码表示的DNA,矩阵的行数为种群数目x_pop = pop[:,0:DNA_SIZE]#取前DNA_SIZE个列表示xy_pop = pop[:,DNA_SIZE:DNA_SIZE*2] ##取中间DNA_SIZE个列表示yz_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,zdef 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     #孩子先得到父亲的全部基因(这里我把一串二进制串的那些0,1称为基因)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_popdef select(pop, fitness):    # nature selection wrt pop's fitness#idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True,fitnew = fitnessfor index in range(len(fitnew)):if fitnew[index] <0:fitnew[index]=0p=(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 randomDNA_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]  # x3def F(x, y, z):val = x * x - x * y + zreturn valdef 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个列表示xy_pop = pop[:, DNA_SIZE:DNA_SIZE * 2]  # 取中间DNA_SIZE个列表示yz_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, zdef 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  # 孩子先得到父亲的全部基因(这里我把一串二进制串的那些0,1称为基因)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_popdef select(pop, fitness):  # nature selection wrt pop's fitnessidx = 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

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

  1. 遗传算法求三元函数极值(python)-采用实数编码

    遗传算法求三元函数极值(python)-采用实数编码 想看二进制编码编码的博客地址在这 遗传算法求三元函数极值(python)-采用二进制编码 本文的遗传算法采用实数编码求三元函数极值 所求函数为 ` ...

  2. 遗传算法求二元函数极值怎么编码_使用遗传算法求二元函数的最小值

    二元函数为y=x1^2+x2^2,x∈[-5,5] NIND=121; %初始种群的个数(Number of individuals) NVAR=2; %一个染色体(个体)有多少基因 PRECI=20 ...

  3. 遗传算法求二元函数极值怎么编码_遗传算法求解一元函数二元函数最值

    ##--------------------------施工中----------------------------## import random import math import numpy ...

  4. 遗传算法求二元函数极值怎么编码_遗传算法求解二元函数极值源码

    网上看到了一个比较不错的讲解遗传算法的帖子,链接如下 http://blog.csdn.net/b2b160/article/details/4680853 但是却没有贴源代码,正好最近闲来无事,就尝 ...

  5. 遗传算法求二元函数极值怎么编码_用遗传算法求复杂函数的极值点

    确定遗传 在元素个体,遗传得到的个体和变异个体中选取最好的30个个体(对应的函数值最大的30个个体)作为下一次迭代的父样本. from random import randint from numpy ...

  6. 遗传算法之求取函数极值

    遗传算法之求取函数极值 1.前言 在智能控制(刘金琨)这本里面讲了遗传算法求取函数极值的方法,这里给出一些个人理解时的注释,顺带 求解了第10章的课后习题第二题. 遗传算法流程图如下: 2.原书案例 ...

  7. python多元函数求解_使用遗传算法求二元函数的最小值

    二元函数为y=x1^2+x2^2,x∈[-5,5] NIND=121; %初始种群的个数(Number of individuals) NVAR=2; %一个染色体(个体)有多少基因 PRECI=20 ...

  8. python多元函数求极小值_使用遗传算法求二元函数的最小值

    二元函数为y=x1^2+x2^2,x∈[-5,5] NIND=121; %初始种群的个数(Number of individuals) NVAR=2; %一个染色体(个体)有多少基因 PRECI=20 ...

  9. 三元函数的几何图形一般是_如何求三元函数的极值?

    this.p={ m:2, b:2, loftPermalink:'', id:'fks_082066084085080066087095074065081087082066093087080', b ...

最新文章

  1. 计算机系统安装和维护实验,2计算机系统安装维护实验报告.doc
  2. 双指针问题最简单的教程(1)
  3. linux mysql8.0 rpm安装_Linux(CentOS7)使用 RPM 安装 mysql 8.0.11的教程
  4. JavaScript中字符串去掉特殊字符和转义字符
  5. css select-style属性,beautifulsoupcss Select查找不存在特定属性(style for ex)的标记
  6. vector中的圆括号和花括号
  7. java 304_分析HTTP请求返回304状态码
  8. Powerful Sleep(神奇的睡眠-睡眠生物钟的秘密:如何睡得更少却睡得更好)阅读笔记...
  9. matlab中使用libsvm工具箱训练的svm分类器model保存
  10. 境外WiFi市场持续升温2016年或迎普及元年
  11. Delphi Access violations 问题的解决之道[转]
  12. mybatis关联查询resultmap的使用详解resultmap
  13. ECharts官网实例
  14. PPT实现单页点名的方式
  15. 【全部译文】Deep-Waveform: A Learned OFDM Receiver Based on Deep Complex Convolutional Networks
  16. SystemTap笔记03 stap的event和handler
  17. linux debian安装字体,Debian安装/设置笔记(字体设置)
  18. Lazada市场大数据分析,东南亚年轻群体的消费趋势!
  19. 一点知识丨Base64 的图片如何完美复制到系统粘贴板
  20. 2022.11.16 英语背诵

热门文章

  1. java voliate 关键字
  2. 刘宇翔第一次作业的一些总结
  3. 理工科的人写文章也是非常好的
  4. 利用反汇编调试与补码解释0x80000000 / -1整形输出异常不一致
  5. Saving James Bond - Hard Version
  6. Kenken Race
  7. 微信最新版本android miui,小米MIUI更新,推送Android 11版系统、4个版本用户可以升级...
  8. java-php-net-python-个人理财管理系统答辩PPT计算机毕业设计程序
  9. 【清华夏令营2016模拟5.31】图样
  10. c++模型推理时 HWC转CHW