0
点赞
收藏
分享

微信扫一扫

遗传算法单种群

小编 2022-01-20 阅读 52
算法
'''
Welcome to GDB Online.
GDB online is an online compiler and debugger tool for C, C++, Python, Java, PHP, Ruby, Perl,
C#, VB, Swift, Pascal, Fortran, Haskell, Objective-C, Assembly, HTML, CSS, JS, SQLite, Prolog.
Code, Compile, Run and Debug online from anywhere in world.
'''
 
 
import numpy as np
import random
import time
import threading
import datetime
 
global SIZE1
SIZE1 = 64  # 控制测试数据范围大小
global SIZE
SIZE = 5  # 控制种群规模
global CSIZEl
CSIZEl = 21
global G
G = 2000  # 控制进化代数
global CRP
CRP = 0.9  # 交叉算子
global MUP
MUP = 0.3  # 变异算子
global CN
CN = 15
global N
N = 3  # N  输入数据个数
 
#结构体
class individual(object):
	def __init__(self):
		self.chrom = [0 for x in range(0,CSIZEl + 1)] # 染色体编码
		self.p = [0 for x in range(0,N)] # 测试数据
		self.fitness = 0.0 # 适应值函数
 
#编码
def code(p,chrom):
    global CSIZEl
    global N
    l = 0
    while l < CSIZEl:#0<21
        i = l // (CSIZEl // N)
        t = p[i]
        j = 0 # j为计数器,确保每个数据对应7位2进制数
        while ( t!=0 ):
            if (t % 2 == 1):
                chrom[l] = 1
                l = l + 1
                j = j + 1
            else:
                chrom[l] = 0
                l = l + 1
                j = j + 1
            t //= 2
        while (j < (CSIZEl // N)):#j<7
            chrom[l] = 0
            l = l + 1
            j = j + 1
    chrom[l] = '\0'
 
#解码函数
def uncode(p,chrom):
    global CSIZEl
    global N
    global SIZE1
    l = 0
    while(l<CSIZEl):
    #for l in range(0 , CSIZEl):
        i = l // (CSIZEl // N)
        #print("第",l,"次循环")
        t = 0
        m = 1
        j = 0 #j为计数器,确保每个数据对应7位2进制数
        while (j < (CSIZEl // N)): #当j小于7
            #print("这是j:",j)
            t = t + int( chrom[l] ) * m
            #print("这是t:",t)
            #print("l的值:", l)
            l += 1
            m *= 2
            j += 1
#        p[i] = t % SIZE1 + 1
        p[i] = t
 
#选择函数
def selection(population):
    max = 0.0
    sum = 0.0
    global SIZE
    cfitness = [0 for i in range(SIZE)]
    
    newpopulation = [individual() for i in range(SIZE)]#找最大适应值
    max = population[0].fitness
    for i in range(1,SIZE):
        if (max < population[i].fitness):
            max = population[i].fitness
 
    for i in range(SIZE):
		#print(max)
        #print(population[i].fitness)
        #print("-----------")
        sum += max - population[i].fitness #用最大值减去适应值, 适应值越小,越容易被选到
        #print("这是第",i,"次循环")
        #print("这是max的值:",max)
        #print("这是population[i].fitness的值:", population[i].fitness)
        #print("这是max - population[i].fitness的值:", max - population[i].fitness)
        #print("这是sum的值:", sum)
        #print("-------------------------------")
    if sum != 0:
        for i in range(SIZE):
            cfitness[i] = (max - population[i].fitness) / sum
        for i in range(SIZE):
            cfitness[i] = cfitness[i - 1] + cfitness[i]
 
    for i in range(SIZE):
        p = random.randint(0,1000) / 1000.0
        index = 0
        # 比值越小,越容易被选到,因为cfitness[i] = cfitness[i - 1] + cfitness[i] = (max - population[i].fitness) / sum
        # 适应值越大,max - population[i].fitness越小,越容易被选到
        if sum != 0:
            while (p > cfitness[index]):
                index += 1
                if index >= SIZE:
                    break
 
        for j in range(N):
            if index >= SIZE:
                break
            newpopulation[i].p[j] = population[index].p[j]
            
 
        for i in range(SIZE):
            for j in range(N):
                population[i].p[j] = newpopulation[i].p[j]
		
#单点交叉函数
def cross1(population):
    global SIZE
    global CSIZEl
    global CRP
    index = [0 for x in range(SIZE)]
    for i in range(SIZE):
        index[i] = i
    for i in range(SIZE):
        point = random.randint(0, SIZE - i - 1)
        temp = index[i]
        index[i] = index[point + i]
        index[point + i] = temp
 
    for i in range(0,SIZE-1,2):
        cm = random.randint(0,1000) / 1000.0
        if (cm <= CRP):
            cn = random.randint(0,CSIZEl)  #printf("----------交叉点是%d\n", cn);
        #     global j
        #     j = cn
        #     global index_i
        #     index_i = population[index[i]].chrom
        #     global index_imore1
        #     index_imore1 = population[index[i + 1]].chrom
        # while j < CSIZEl: 
        #     t = index_i[j]
        #     index_i[j] = index_imore1[j]
        #     index_imore1[j] = t
        #     j += 1
        # population[index[i]].chrom = index_i
        # population[index[i + 1]].chrom = index_imore1
            
        for j in range(CSIZEl):
            t = population[index[i]].chrom[j]
            population[index[i]].chrom[j] = population[index[i + 1]].chrom[j]
            population[index[i + 1]].chrom[j] = t		
		
def mutation(population):
    global SIZE
    global MUP
    global CSIZEl
    for n in range(0,SIZE):
        p = random.randint(0 , 1000) / 1000.0
        if (p < MUP):
            mn = random.randint(0,CSIZEl)
            if (population[n].chrom[mn] == 1):
                population[n].chrom[mn] = 0
            else:
                population[n].chrom[mn] = 1
 
def fun(tt0,mb0):
    global CN
    f = 0.0
    min = 0.0
    sl0 = 0
    ml0 = 0
    l0 = 0
    l1 = 0
    l2 = 0
    for j in range(CN):#5次循环
        if (tt0[j] != 0):
            sl0 += 1
            
    for j in range(CN):
        if (mb0[j] != 0):
            ml0 = ml0 + 1
            
    l0 = max(ml0, sl0)  # 穿越路径与目标路径相比,进程的最长路径长度
    
    for i in range(l0):
        if (tt0[i] != mb0[i]):
            break #连续相同的节点个数即曾接近度,越大越好
        #print(i)
        #print(l0)
        #print("----------")
    f = i / l0
    #print("这是f:",f)
    return f		
		
def elite(population,jy):
    global SIZE
    m = 0.0
    for i in range(SIZE):
        if (population[i].fitness > m):
            m = population[i].fitness
            for j in range(N):
                jy.p[j] = population[i].p[j]
                jy.fitness = population[i].fitness		
		
def compare(population,jy):
    global SIZE
    max = 0.0
    min = population[0].fitness
    for i in range(SIZE):
        if (population[i].fitness > max):
            max = population[i].fitness
    for i in range(SIZE):
        if (population[i].fitness < min):
            min = population[i].fitness
            indexm = i
    if (max < jy.fitness):
        population[indexm].fitness = jy.fitness
        for j in range(N):
            population[indexm].p[j] = jy.p[j]
			
def Tr(a,tt):
    global CN
    x = a[0]
    y = a[1]
    z = a[2]
    k = 0
    for i in range(CN):
        tt[i] = 0
    tt[k] = 1
    k = k +1
    if (x > y):
        tt[k] = 2
        k = k + 1
        t = x
        x = y
        y = t
    tt[k] = 3
    k = k + 1
    if (x > z):
        tt[k] = 4
        k = k +1
        t = x
        x = z
        z = t
    tt[k] = 5
    k = k + 1
    if (y > z):
        tt[k] = 6
        k = k + 1
        t = y
        y = z
        z = t
    tt[k] = 7
    k = k + 1
    if (x + y <= z):
        tt[k] = 8
        k = k + 1
        type = 0
    else:
        tt[k] = 9
        k = k + 1
        if (x * x + y * y == z * z):
            tt[k] = 10
            k = k + 1
            type = 1
        else:
            tt[k] = 11
            k = k + 1
            if ((x == y) and (y == z)):
                tt[k] = 12
                k = k + 1
                type = 2
            else:
                tt[k] = 13
                k = k + 1
            if (x == y or y == z):
                tt[k] = 14
                k = k + 1
                type = 3
            else:
                tt[k] = 10
                k = k + 1
                type = 4		
		
def main():
    i = 0
    j = 0
    k = 0
    g = 0
    count = 0
    global population
    global SIZE
    global G
    population = [individual() for i in range(SIZE)]
    flag0 = 0
    flag1 = 0
    flag2 = 0
    global mb0
    mb0 = [1,2,3,5,7,9,10,0,0,0,0,0,0,0,0]
    global mb1
    mb1 = [1, 3, 4, 5, 7, 9, 11, 13, 14, 0,0,0,0,0,0]
    global mb2
    mb2 = [1, 3, 5, 7, 8, 0,0,0,0,0,0,0,0,0,0]
    global a
    a = np.zeros(N, dtype=int)
    global tt0
    tt0 = [(np.zeros(CN, dtype=int)) for j in range(SIZE)]#不可以浅拷贝,我们以浅拷贝方式创建的列表,里面的列表的内存是指向同一块,不管我们修改哪个列表,其他两个列表也会跟着改变
    for i in range(SIZE):
        for j in range(N):
            population[i].p[j] = (np.random.randint(0,SIZE1) + 1)
            
    print("循环开始: ",datetime.datetime.now())
    for count in range(G):
        for k in range(SIZE):
            if(population[k].p[0] != 0 and population[k].p[1] != 0 and population[k].p[2] != 0  ):
                a[0] = population[k].p[0]
                a[1] = population[k].p[1]
                a[2] = population[k].p[2]
            if (flag0 == 1 and flag1 == 1 and flag2 == 1):
                break
            if (flag0 == 0 or flag1 == 0 or flag2 == 0):
                Tr(a, tt0[k])
            if (flag0 == 0):
                for j in range(CN):
                    if (tt0[k][j] != mb0[j]):
                        break
                if (j == CN - 1):
                    flag0 = 1
                    print("目标路径{1,2,3,5,7,9,11,13,15,0}在第",count,"代进化方法找到数据", a[0], a[1], a[2])
            if (flag1 == 0):
                for j in range(CN):
                    if (tt0[k][j] != mb1[j]):
                        break
                if (j == CN - 1):
                    flag1 = 1
                    print("目标路径{1,3,4,5,7,9,11,13,14,0}在第",count+1,"代进化方法找到数据", a[0], a[1], a[2])
            if (flag2 == 0):
                for j in range(CN):
                    if (tt0[k][j] != mb2[j]):
                        break
                if (j == CN - 1):
                    flag2 = 1
                    print("目标路径{1,3,5,7,8,0};在第",count+1,"代进化方法找到数据", a[0], a[1], a[2])
        if (flag0 == 0 or flag1 == 0 or flag2 == 0):
            if (flag0 == 0):
                for k in range(SIZE):
                    population[k].fitness = fun(tt0[k], mb0)
            if (flag1 == 0 and flag2 == 0 and flag0 == 1):
                for k in range(SIZE):
                    population[k].fitness = fun(tt0[k], mb1)
            if (flag2 == 0 and flag1 == 1 and flag0 == 1):
                for k in range(SIZE):
                    population[k].fitness = fun(tt0[k], mb2)
            selection(population)
            for k in range(SIZE):
                code(population[k].p, population[k].chrom) # 编码
            cross1(population) # 单点交叉
            mutation(population) # 变异操作
            for k in range(SIZE):
                uncode(population[k].p, population[k].chrom) # 解码
    if (flag0 == 0):
        print("目标路径{1,2,3,5,7,9,11,13,15,0}进化法迭代",count+1,"代仍然寻找路径失败")
    if (flag1 == 0):
        print("目标路径{1,3,4,5,7,9,11,13,14,0}进化法迭代",count+1,"代仍然寻找路径失败")
    if (flag2 == 0):
        print("目标路径{1,3,5,7,8,0}进化法迭代",count+1,"代仍然寻找路径失败")
    print("循环结束: ",datetime.datetime.now())
 

 
if __name__ == '__main__':
    main()		
 
举报

相关推荐

0 条评论