'''
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()