ga.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. # ga.py
  2. import numpy as np
  3. import random
  4. import fit_funcs
  5. from sampling import *
  6. class Individual:
  7. def __init__(self, dna, pop_seed_name):
  8. self.dna = dna
  9. self.dna_len = len(dna)
  10. self.pop_seed_name = pop_seed_name
  11. self.f = []
  12. self.choose_time = 0
  13. self.error_number = None
  14. self.list_er = []
  15. def __lt__(self, other):
  16. if self.f[0] > other.f[0]:
  17. return True
  18. return False
  19. def get_fitness(self, F, domain_flags, data_collection_para):
  20. # len_F = len(F)
  21. # fitness = np.zeros(shape=len_F)
  22. # for i in range(len_F):
  23. fitness, error_number, list_er = F(self.dna, self.pop_seed_name, self.error_number, self.choose_time,
  24. self.list_er, domain_flags, data_collection_para)
  25. print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", type(fitness))
  26. return fitness, error_number, list_er
  27. # def cross_newObj(self, p1, p2,iterate_time):
  28. # # 不能修改之前的,需要生成一个新的对象
  29. # p1_dna = p1.dna.copy()
  30. # p2_dna = p2.dna.copy()
  31. # cut_i = np.random.randint(1, self.dna_len - 1)
  32. # temp = p1_dna[cut_i:].copy()
  33. # p1_dna[cut_i:] = p2_dna[cut_i:]
  34. # p2_dna[cut_i:] = temp
  35. # cross_name=p1.pop_seed_name.split("_")
  36. # p1_name="seed_"+iterate_time+"_1_"+cross_name[3]
  37. # cross_name=p2.pop_seed_name.split("_")
  38. # p2_name="seed_"+iterate_time+"_2_"+cross_name[3]
  39. # q1 = individual(p1_dna,p1_name)
  40. # q2 = individual(p2_dna,p2_name)
  41. # return q1, q2
  42. def cross(self, p1, p2):
  43. cut_i = np.random.randint(1, self.dna_len - 1)
  44. temp = p1[cut_i:].copy()
  45. p1[cut_i:] = p2[cut_i:]
  46. p2[cut_i:] = temp
  47. return p1, p2
  48. # def mutation(self, domain):
  49. # point = np.random.randint(0, self.dna_len)
  50. # low = domain[point][0]
  51. # high = domain[point][1]
  52. # self.dna[point] = random.randint(low,high)
  53. # return self.dna
  54. # 实数编码,SBX交叉
  55. def cross_newObj(self, domain, p1, p2, iterate_time, m, n):
  56. eta_c = 10
  57. pcross_real = 1.0 # ori : 0.9
  58. # 如果随机概率大于交叉概率则不进行交叉操作
  59. p1_dna = p1.dna.copy()
  60. p2_dna = p2.dna.copy()
  61. if random.random() <= pcross_real:
  62. # 对两个个体执行SBX交叉操作
  63. for j in range(self.dna_len):
  64. # 判断是否对某自变量交叉
  65. if random.random() > 0.5:
  66. continue
  67. # 如果两个体某自变量相等则不操作
  68. if p1_dna[j] == p2_dna[j]:
  69. continue
  70. # 对某自变量交叉
  71. y1 = min(p1_dna[j], p2_dna[j])
  72. y2 = max(p1_dna[j], p2_dna[j])
  73. ylow = domain[j][0]
  74. yup = domain[j][1]
  75. r = random.random()
  76. beta = 1.0 + (2.0 * (y1 - ylow) / (y2 - y1))
  77. alpha = 2.0 - beta ** (-(eta_c + 1.0))
  78. if r <= (1.0 / alpha):
  79. betaq = (r * alpha) ** (1.0 / (eta_c + 1.0))
  80. else:
  81. betaq = (1.0 / (2.0 - r * alpha)) ** (1.0 / (eta_c + 1.0))
  82. child1 = 0.5 * ((y1 + y2) - betaq * (y2 - y1))
  83. beta = 1.0 + (2.0 * (yup - y2) / (y2 - y1))
  84. alpha = 2.0 - beta ** (-(eta_c + 1.0))
  85. if r <= (1.0 / alpha):
  86. betaq = (r * alpha) ** (1.0 / (eta_c + 1.0))
  87. else:
  88. betaq = (1.0 / (2.0 - r * alpha)) ** (1.0 / (eta_c + 1.0))
  89. child2 = 0.5 * ((y1 + y2) - betaq * (y2 - y1))
  90. if str(child1) == 'nan':
  91. child1 = 0
  92. if str(child2) == 'nan':
  93. child2 = 0
  94. child1 = min(max(child1, ylow), yup)
  95. child2 = min(max(child2, ylow), yup)
  96. p1_dna[j] = child1
  97. p2_dna[j] = child2
  98. cross_name = p1.pop_seed_name.split("_")
  99. p1_name = "seed_" + iterate_time + "_" + str(m) + "_" + cross_name[3]
  100. cross_name = p2.pop_seed_name.split("_")
  101. p2_name = "seed_" + iterate_time + "_" + str(n) + "_" + cross_name[3]
  102. q1 = Individual(p1_dna, p1_name)
  103. q2 = Individual(p2_dna, p2_name)
  104. return q1, q2
  105. def mutation(self, domain, pm):
  106. eta_m = 5
  107. for j in range(self.dna_len):
  108. r = random.random()
  109. # 对个体某变量进行变异
  110. if r <= pm:
  111. y = self.dna[j]
  112. ylow = domain[j][0]
  113. yup = domain[j][1]
  114. delta1 = 1.0 * (y - ylow) / (yup - ylow)
  115. delta2 = 1.0 * (yup - y) / (yup - ylow)
  116. # delta=min(delta1, delta2)
  117. r = random.random()
  118. mut_pow = 1.0 / (eta_m + 1.0)
  119. if r <= 0.5:
  120. xy = 1.0 - delta1
  121. val = 2.0 * r + (1.0 - 2.0 * r) * (xy ** (eta_m + 1.0))
  122. deltaq = val ** mut_pow - 1.0
  123. else:
  124. xy = 1.0 - delta2
  125. val = 2.0 * (1.0 - r) + 2.0 * (r - 0.5) * (xy ** (eta_m + 1.0))
  126. deltaq = 1.0 - val ** mut_pow
  127. y = y + deltaq * (yup - ylow)
  128. y = min(yup, max(y, ylow))
  129. self.dna[j] = y
  130. print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", self.dna)
  131. print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", "77777777777777777777777777777")
  132. class ga:
  133. def __init__(self, pri_queue_size, pop_size, dna_size, pc, pm, f_funcs, domain, domain_flags):
  134. self.pri_queue_size = pri_queue_size
  135. self.pop_size = pop_size
  136. self.dna_size = dna_size
  137. # self.f_size = len(f_funcs)
  138. self.pc = pc
  139. self.pm = pm
  140. self.f_funcs = f_funcs
  141. self.domain = domain
  142. self.domain_flags = domain_flags
  143. def ini_pop(self, if_sampling):
  144. rseed = 8.35
  145. random.seed(rseed)
  146. if not if_sampling:
  147. # 24x8 随机参数矩阵 初始种群24x可变参数8
  148. P_dna = np.random.random_integers(0, 0, size=(self.pop_size, self.dna_size))
  149. for i in range(self.pop_size):
  150. for j in range(len(self.domain)):
  151. item = self.domain[j]
  152. P_dna[i, j] = random.randint(item[0], item[1])
  153. print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", P_dna)
  154. P = [] # 初始种群P\
  155. Seed_ini = []
  156. for j in range(self.pop_size):
  157. seed = "seed_0_" + str(j + 1) + "_" + str(int(j / 4) + 1) + ".xosc"
  158. Seed_ini.append(seed)
  159. for m in range(self.pop_size):
  160. P.append(Individual(P_dna[m], Seed_ini[m]))
  161. else:
  162. # 72x8
  163. P_dna = np.random.random_integers(0, 0, size=(3 * self.pop_size, self.dna_size))
  164. # print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", P_dna)
  165. for i in range(3 * self.pop_size):
  166. for j in range(len(self.domain)):
  167. item = self.domain[j]
  168. P_dna[i, j] = random.randint(item[0], item[1])
  169. print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", P_dna)
  170. P = [] # 初始种群P\
  171. Seed_ini = []
  172. Sample_predict = []
  173. choose = [0, 0, 0, 0, 0, 0]
  174. choose_result = []
  175. for j in range(3 * self.pop_size):
  176. print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", "Sampling # ", j)
  177. # 前25个 前12:0_j+1_4 后12:0_j+1_5 0_25_6
  178. if int(j / 12) + 4 <= 6:
  179. num = int(j / 12) + 4
  180. seed = "seed_0_" + str(j + 1) + "_" + str(num) + ".xosc"
  181. # 26-72个 0_26_1 0_27_1 ... 0_49_2 0_50_2... 0_61_
  182. else:
  183. num = int((j-36)/ 12 + 1)
  184. seed = "seed_0_" + str(j + 1) + "_" + str(num) + ".xosc"
  185. print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", "Generate seed_name: ", seed)
  186. #seed = "seed_0_" + str(j + 1) + "_" + str(int(j / 12) + 1) + ".xosc"
  187. Seed_ini.append(seed)
  188. cal_number = sample_simulate(P_dna[j, 0], P_dna[j, 1], P_dna[j, 2], P_dna[j, 3], P_dna[j, 4],
  189. P_dna[j, 5], P_dna[j, 6], P_dna[j, 7], seed, self.domain_flags)
  190. Sample_predict.append(cal_number)
  191. print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", "*******************")
  192. print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", "VGG error num:"+str(cal_number))
  193. with open('r_list.csv', 'a+', encoding='utf-8') as l: # save entropy
  194. cw = csv.writer(l)
  195. cw.writerow([seed, P_dna[j], cal_number])
  196. print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", Sample_predict)
  197. Sample_predict = np.array(Sample_predict)
  198. # 加负号后按从大到小排序
  199. result = np.argsort(-Sample_predict)
  200. # result为错误数排序后的下标索引数组
  201. print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", "Sample_predict result:", result)
  202. for m in range(3 * self.pop_size): # select top 4 seed of every scene( 4 * 6 ) from 72 seeds
  203. # 12应该为pop_size * 3 / seed_num
  204. loc = int(result[m] / 12)
  205. print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", "loc:", loc)
  206. # 4应该为pop_size / seed_num
  207. if (choose[loc] < 4):
  208. choose[loc] = choose[loc] + 1
  209. choose_result.append(result[m])
  210. print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", "Sample choose_result:", choose_result)
  211. for m in range(self.pop_size):
  212. # print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", P_dna[m])
  213. # print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", Seed_ini[m])
  214. P.append(Individual(P_dna[choose_result[m]], Seed_ini[choose_result[m]]))
  215. return P
  216. # def calculate_pop_fitness(self, pop, total):
  217. # # 计算Pop适应度,存储到individual中
  218. # normalization = []
  219. # #for p in pop:
  220. # # if p.f == None:
  221. # # p.f, p.error_number, p.list_er = p.get_fitness(self.f_funcs, total)
  222. # for p in pop:
  223. # p.f, p.error_number, p.list_er = p.get_fitness(self.f_funcs, total)
  224. # print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", p.f)
  225. # return pop
  226. def run_sim(self, R,
  227. data_collection_para): # data_collection_para : [is_new_seed(for entropy), is_err_collection(collect err or not), err_type(collect normal(1)/sampling(2)/random data(3))]
  228. for p in R:
  229. print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", "Run sim index: # ", R.index(p))
  230. p.f, p.error_number, p.list_er = p.get_fitness(self.f_funcs, self.domain_flags, data_collection_para)
  231. print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", p.f, '\n')
  232. def select(self, R):
  233. R.sort()
  234. choose_number = [0, 0]
  235. # print("[" + os.path.basename(__file__) + ", Line " + str(sys._getframe().f_lineno) + ", " + sys._getframe().f_code.co_name + "] ", len(R))
  236. pop = []
  237. for i in range(2):
  238. randomnumber1 = random.randint(0, self.pop_size - 1)
  239. randomnumber2 = random.randint(0, self.pop_size - 1)
  240. randomnumber3 = random.randint(0, self.pop_size - 1)
  241. randomnumber4 = random.randint(0, self.pop_size - 1)
  242. if R[randomnumber1].f > R[randomnumber2].f:
  243. pop.append(R[randomnumber1])
  244. choose_number[0] = randomnumber1
  245. else:
  246. pop.append(R[randomnumber2])
  247. choose_number[0] = randomnumber2
  248. if R[randomnumber3].f > R[randomnumber4].f:
  249. pop.append(R[randomnumber3])
  250. choose_number[1] = randomnumber3
  251. else:
  252. pop.append(R[randomnumber4])
  253. choose_number[1] = randomnumber4
  254. R[choose_number[0]].choose_time = R[choose_number[0]].choose_time + 1
  255. R[choose_number[1]].choose_time = R[choose_number[1]].choose_time + 1
  256. return pop, R
  257. def pop_cross(self, P, iterate_time):
  258. new_Q = []
  259. i = 0
  260. P_len = len(P)
  261. while i < P_len:
  262. # q1, q2 = P[i].cross_newObj(P[i], P[i + 1],str(iterate_time))
  263. q1, q2 = P[i].cross_newObj(self.domain, P[i], P[i + 1], str(iterate_time), (i + 1), (i + 2))
  264. new_Q.append(q1)
  265. new_Q.append(q2)
  266. i += 2
  267. return new_Q
  268. def pop_mutation(self, Q):
  269. for q in Q:
  270. q.mutation(self.domain, self.pm)
  271. return Q
  272. def calulate_pop(self, R, pri_queue_size):
  273. R.sort()
  274. return R[:pri_queue_size]
  275. def calculate_pop_fitness(self, R):
  276. fit_funcs.cal_fitness(R)
  277. normalization = []
  278. for r in R:
  279. normalization.append(r.f[2])
  280. max_val = max(normalization)
  281. min_val = min(normalization)
  282. minus = max_val - min_val if max_val - min_val != 0 else 1
  283. for r in R:
  284. r.f[0] += r.f[1] + (r.f[2] - min_val) / minus