dna2.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import random
  2. def f(x):
  3. if x >= 5 :
  4. return x+5
  5. else :
  6. return -x+5
  7. def create_init_DNA(min,max):
  8. # out: DNA(['0','1',....])
  9. ret = random.randint(min,max)
  10. return int_to_bin(ret)
  11. def int_to_bin(x):
  12. # in: int_DNA(int)
  13. # out: DNA
  14. ret = []
  15. if x >= 0:
  16. ret.append(0)
  17. else:
  18. ret.append(1)
  19. x = -x
  20. for i in [32768,16384,8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1] :
  21. if x>=i :
  22. ret.append(1)
  23. x -= i
  24. else :
  25. ret.append(0)
  26. return ret
  27. def bin_to_int(x):
  28. # in: DNA
  29. # out: int_DNA(int)
  30. ret = 0
  31. new_x = x[:]
  32. flag = -(int(new_x[0])*2-1)
  33. mul = 1
  34. new_x = reversed(new_x)
  35. new_x.pop()
  36. for i in new_x :
  37. ret += flag * int(i) * mul
  38. mul *= 2
  39. return ret
  40. def reversed(x):
  41. ret = []
  42. for i in range(0,len(x)):
  43. ret.append(x[-i-1])
  44. return ret
  45. def create_DNAs(num,min,max):
  46. # in: num(int)
  47. # out: DNAs([DNA,DNA,...])
  48. ret = []
  49. for i in range(num):
  50. ret.append(create_init_DNA(min,max))
  51. return ret
  52. def bins_to_ints(x):
  53. # in: DNAs
  54. # out: int_DNAs([int,int,...])
  55. ret = []
  56. for i in x:
  57. ret.append(bin_to_int(i))
  58. return ret
  59. def ints_to_bins(x):
  60. # in: int_DNAs
  61. # out: DNAs
  62. ret = []
  63. for i in x:
  64. ret.append(int_to_bin(i))
  65. return ret
  66. def create_probabilitys(x):
  67. # in: DNAs
  68. # out: probabilitys([float,float...])
  69. scores = survival_scores(x)
  70. mid = []
  71. ret = []
  72. sum = 0
  73. for i in scores:
  74. sum+=i
  75. for i in scores:
  76. mid.append(1/(i+0.0/sum))
  77. sum = 0
  78. for i in mid:
  79. sum+=i
  80. for i in mid:
  81. ret.append(i/sum)
  82. return ret
  83. def survival_scores(x):
  84. # in: DNAs
  85. # out: survival_scores[f(int_DNA),...]
  86. ret = []
  87. for i in x:
  88. ret.append(f(bin_to_int(i)/100))
  89. return ret
  90. def choose_DNA(DNAs,probabilitys):
  91. # in: DNAs,probabilitys
  92. # out: choosen_DNA(DNA)
  93. # probabilitys是由若干(0,1)之间的浮点数组成的数组,这些浮点数的和为1
  94. i = 0 # i记录取出元素的位置
  95. ran = random.random()
  96. max_sum = 0
  97. for max in probabilitys :
  98. max_sum += max
  99. if i != 0 :
  100. min_sum += probabilitys[i-1]
  101. else :
  102. min_sum = 0
  103. if (ran < max_sum) and (ran >= min_sum) :
  104. return DNAs[i]
  105. i += 1
  106. def mating_DNAs(DNAs,num=None):
  107. # in: DNAs,num(int)交配组DNA数量
  108. # out: mating_DNAs(DNAs)交配组
  109. num = num or len(DNAs)
  110. ret = []
  111. for i in range(num) :
  112. ret.append(choose_DNA(DNAs,create_probabilitys(DNAs)))
  113. return ret
  114. def son_DNA(DNAs):
  115. # in: mating_DNAs(DNAs)交配组
  116. # out: son_DNA(DNA)交叉互换后产生的子代
  117. father = DNAs[random.randint(0,len(DNAs)-1)]
  118. mother = DNAs[random.randint(0,len(DNAs)-1)]
  119. pos = random.randint(0,len(DNAs[0])-1)
  120. son_DNA = []
  121. son_DNA += father[0:pos]
  122. son_DNA += mother[pos+1:-1]
  123. return son_DNA
  124. def mutation(DNA,part_rate):
  125. # in: son_DNA(DNA)交叉互换后的子代,part_rate(float)碱基对变异概率
  126. # out: mut_DNA(DNA)变异后的子代
  127. ret = DNA[:]
  128. for i in range(len(ret)):
  129. k = random.random()
  130. if k < part_rate :
  131. ret[i] = str(-int(ret[i])+1)
  132. return ret
  133. def next_DNAs(DNAs,father_rate,part_rate,mut_rate,num):
  134. # in: mating_DNAs(DNAs),father_rate(float)父代保留占比,part_rate(float)碱基对突变概率,mut_rate(float)生物变异概率,num(int)下一代数量
  135. # out: next_DNAs(DNAs)
  136. ret = []
  137. pro_DNAs = create_probabilitys(DNAs)
  138. father_num = int(father_rate*num+0.5)
  139. son_num = num - father_num
  140. i = 1
  141. for pro in reversed(sorted(pro_DNAs)):
  142. if i > father_num:
  143. break
  144. ret.append(DNAs[pro_DNAs.index(pro)])
  145. i += 1
  146. for s in range(son_num):
  147. k = random.random()
  148. son_DNA=(mating_DNAs(DNAs)[0])
  149. if k < mut_rate :
  150. son_DNA = mutation(son_DNA,part_rate)
  151. ret.append(son_DNA)
  152. return ret
  153. def iterate(DNAs,father_rate,part_rate,mut_rate,iter_num,population):
  154. # in: DNAs父代,father_rate(float)每一次迭代保留父代的占比, num(int)迭代次数,population(int)种群数量
  155. # out: DNAs子代
  156. ret = eval(repr(DNAs))
  157. for i in range(iter_num):
  158. ret = next_DNAs(ret,father_rate,part_rate,mut_rate,population)
  159. return ret
  160. def 百分比化(a):
  161. b = str(a*100)[0:5]
  162. return f'{b}%'
  163. a = create_DNAs(5,-9999,9999)