| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- import random
- def f(x):
- if x >= 5 :
- return x+5
- else :
- return -x+5
- def create_init_DNA(min,max):
- # out: DNA(['0','1',....])
- ret = random.randint(min,max)
- return int_to_bin(ret)
- def int_to_bin(x):
- # in: int_DNA(int)
- # out: DNA
- ret = []
- if x >= 0:
- ret.append(0)
- else:
- ret.append(1)
- x = -x
- for i in [32768,16384,8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1] :
- if x>=i :
- ret.append(1)
- x -= i
- else :
- ret.append(0)
- return ret
- def bin_to_int(x):
- # in: DNA
- # out: int_DNA(int)
- ret = 0
- new_x = x[:]
- flag = -(int(new_x[0])*2-1)
- mul = 1
- new_x = reversed(new_x)
- new_x.pop()
- for i in new_x :
- ret += flag * int(i) * mul
- mul *= 2
- return ret
- def reversed(x):
- ret = []
- for i in range(0,len(x)):
- ret.append(x[-i-1])
- return ret
- def create_DNAs(num,min,max):
- # in: num(int)
- # out: DNAs([DNA,DNA,...])
- ret = []
- for i in range(num):
- ret.append(create_init_DNA(min,max))
- return ret
- def bins_to_ints(x):
- # in: DNAs
- # out: int_DNAs([int,int,...])
- ret = []
- for i in x:
- ret.append(bin_to_int(i))
- return ret
- def ints_to_bins(x):
- # in: int_DNAs
- # out: DNAs
- ret = []
- for i in x:
- ret.append(int_to_bin(i))
- return ret
- def create_probabilitys(x):
- # in: DNAs
- # out: probabilitys([float,float...])
- scores = survival_scores(x)
- mid = []
- ret = []
- sum = 0
- for i in scores:
- sum+=i
- for i in scores:
- mid.append(1/(i+0.0/sum))
- sum = 0
- for i in mid:
- sum+=i
- for i in mid:
- ret.append(i/sum)
- return ret
- def survival_scores(x):
- # in: DNAs
- # out: survival_scores[f(int_DNA),...]
- ret = []
- for i in x:
- ret.append(f(bin_to_int(i)/100))
- return ret
- def choose_DNA(DNAs,probabilitys):
- # in: DNAs,probabilitys
- # out: choosen_DNA(DNA)
- # probabilitys是由若干(0,1)之间的浮点数组成的数组,这些浮点数的和为1
- i = 0 # i记录取出元素的位置
- ran = random.random()
- max_sum = 0
- for max in probabilitys :
- max_sum += max
- if i != 0 :
- min_sum += probabilitys[i-1]
- else :
- min_sum = 0
- if (ran < max_sum) and (ran >= min_sum) :
- return DNAs[i]
- i += 1
- def mating_DNAs(DNAs,num=None):
- # in: DNAs,num(int)交配组DNA数量
- # out: mating_DNAs(DNAs)交配组
- num = num or len(DNAs)
- ret = []
- for i in range(num) :
- ret.append(choose_DNA(DNAs,create_probabilitys(DNAs)))
- return ret
- def son_DNA(DNAs):
- # in: mating_DNAs(DNAs)交配组
- # out: son_DNA(DNA)交叉互换后产生的子代
- father = DNAs[random.randint(0,len(DNAs)-1)]
- mother = DNAs[random.randint(0,len(DNAs)-1)]
- pos = random.randint(0,len(DNAs[0])-1)
- son_DNA = []
- son_DNA += father[0:pos]
- son_DNA += mother[pos+1:-1]
- return son_DNA
- def mutation(DNA,part_rate):
- # in: son_DNA(DNA)交叉互换后的子代,part_rate(float)碱基对变异概率
- # out: mut_DNA(DNA)变异后的子代
- ret = DNA[:]
- for i in range(len(ret)):
- k = random.random()
- if k < part_rate :
- ret[i] = str(-int(ret[i])+1)
- return ret
- def next_DNAs(DNAs,father_rate,part_rate,mut_rate,num):
- # in: mating_DNAs(DNAs),father_rate(float)父代保留占比,part_rate(float)碱基对突变概率,mut_rate(float)生物变异概率,num(int)下一代数量
- # out: next_DNAs(DNAs)
- ret = []
- pro_DNAs = create_probabilitys(DNAs)
- father_num = int(father_rate*num+0.5)
- son_num = num - father_num
- i = 1
- for pro in reversed(sorted(pro_DNAs)):
- if i > father_num:
- break
- ret.append(DNAs[pro_DNAs.index(pro)])
- i += 1
- for s in range(son_num):
- k = random.random()
- son_DNA=(mating_DNAs(DNAs)[0])
- if k < mut_rate :
- son_DNA = mutation(son_DNA,part_rate)
- ret.append(son_DNA)
- return ret
- def iterate(DNAs,father_rate,part_rate,mut_rate,iter_num,population):
- # in: DNAs父代,father_rate(float)每一次迭代保留父代的占比, num(int)迭代次数,population(int)种群数量
- # out: DNAs子代
- ret = eval(repr(DNAs))
- for i in range(iter_num):
- ret = next_DNAs(ret,father_rate,part_rate,mut_rate,population)
- return ret
- def 百分比化(a):
- b = str(a*100)[0:5]
- return f'{b}%'
- a = create_DNAs(5,-9999,9999)
|