def run_SPEA2(SIR_name, version, test_size): evaluator = evaluation.VEval(SIR_name, version, test_size) dim = test_size population = GA.initial_genes(dim, GLOB.POP) archive = [] population_history = [population] archive_history = [archive] if GLOB.DEBUG: print('0', len(population)) for i in range(GLOB.MAX_IT): #update union = population + archive GA.evaluate(union, evaluator) get_fitness(union) archive = select(union) population = GA.crossover(archive)[GLOB.POP + 1:] if GLOB.DEBUG: print(i, len(population)) #save history population_history.append(population) archive_history.append(archive) first_pareto = get_first_pareto(archive) #final result return first_pareto
def get_fitness(pop): #get score for each gene for p in pop: score = 0 for q in pop: if GA._is_dominate(q, p): score += 1 p.update_flag({'score': score}) #get raw fitness for each gene for p in pop: raw = 0 for q in pop: if GA._is_dominate(q, p): q_score = q.get_flag("score") raw += q_score p.update_flag({"raw": raw}) #get density and fitness for each gene N = math.ceil(math.sqrt(GLOB.POP + GLOB.MAX_ARCHIVE_SPEA2)) for p in pop: dens = 0 for q in pop: #get distance from others dist = np.linalg.norm(p.get_eval() - q.get_eval()) q.update_flag({'dist': dist}) sorted_pop = sorted(pop, key=lambda gene: gene.get_flag('dist')) dens = sorted_pop[N + 1].get_flag('dist') fitness = dens + p.get_flag('raw') p.update_flag({'dense': dens, 'fitness': fitness})
def new_crossover(CA, DA, cr, mr, dim): ratio = GLOB.CA_DA_RATIO new_pop = [] if len(CA + DA) < 2: new_pop += GA.initial_genes(dim, GLOB.POP) return new_pop elif len(CA) < 2 or len(DA) < 2: new_pop += GA.crossover(CA + DA, mr=mr) return new_pop for i in range(GLOB.POP): child = None # consider crossover rate if random.random() < cr: p1, p2 = None, None # randomly choose parents between CA and DA rand_num = random.random() if rand_num < ratio * ratio: p1, p2 = random.sample(CA, 2) elif rand_num < 2 * ratio - ratio * ratio: if random.random() < 0.5: p1 = random.sample(CA, 1)[0] p2 = random.sample(DA, 1)[0] else: p1 = random.sample(DA, 1)[0] p2 = random.sample(CA, 1)[0] else: p1, p2 = random.sample(DA, 2) child = GA.PMX(p1, p2) else: seq = random.sample(CA + DA, 1)[0].get_seq().copy() child = GA.Gene_Info(seq) # mutation if random.random() < mr: seq = child.get_seq() idx1, idx2 = random.sample(list(seq), 2) seq[idx2], seq[idx1] = seq[idx1], seq[idx2] #check overlap overlapped = False for parent in CA + DA: if (child.get_seq() == parent.get_seq()).all(): overlapped = True break if overlapped: # if overlap, do not add child at new_pop continue new_pop.append(child) return new_pop #run_TAEA('sed',1,360)
def collect_non_dominated(pop, CA, DA): def distance(eval1, eval2): return np.linalg.norm(eval1 - eval2) new_CA = CA[:] new_DA = DA[:] #step1: update CA and DA for i in range(len(pop)): p = pop[i] #check if non dominated p.update_flag({"non-dominated": True, "dominate-other": False}) for archive in new_CA + new_DA: if GA._is_dominate(archive, p): p.update_flag({"non-dominated": False}) break if not p.get_flag("non-dominated"): #skip if not non-dominated continue #check if it dominated other for archive in new_CA: if GA._is_dominate(p, archive): new_CA.remove(archive) p.update_flag({"dominate-other": True}) for archive in new_DA: if GA._is_dominate(p, archive): new_DA.remove(archive) p.update_flag({"dominate-other": True}) if p.get_flag("dominate-other"): #dominate other, add at CA new_CA.append(p) else: #not dominate other, add at DA new_DA.append(p) #step2: limit the size of CA and DA if len(new_CA + new_DA) > GLOB.MAX_ARCHIVE_TAEA: if len(new_CA) > GLOB.MAX_ARCHIVE_TAEA: new_DA = [] return for pop_da in new_DA: pop_da.update_flag({"len": GLOB.LARGE}) for pop_ca in new_CA: dist = distance(pop_da.get_eval(), pop_ca.get_eval()) if dist < pop_da.get_flag("len"): pop_da.update_flag({"len": dist}) #remove some population in DA new_DA = sorted(new_DA, key=lambda pop: pop.get_flag("len")) new_DA = new_DA[-GLOB.MAX_ARCHIVE_TAEA + len(new_CA):] return new_CA, new_DA
def run_NSGA3(input_fname): modify = modifier.modify_testcase(input_fname) dim = modify.get_datasize() reference = get_ref() population = GA.initial_genes(dim,GLOB.POP) population_history = [population] for i in range(GLOB.MAX_IT): new_pop = GA.crossover(population) GA.evaluate(new_pop,modify) pareto = GA.get_pareto(new_pop) new_pop = select(pareto) population = new_pop population_history.append(population) first_pareto = get_first_pareto(population) #final result
def get_ref(): reference = [] for l in GLOB.reference: gene = GA.Gene_Info(None) gene.set_eval = np.array(l) reference.append(gene) return reference
def get_first_pareto(pop): ''' get only first pareto :param pop: :return: ''' return GA.get_pareto(pop)[0]
def read_file(SIR_name, version): ''' Read files in Result directory and get data return data by each MOEA and trial return reference points for the specific SIR program and version data: dictionary, key = MOEA value = 2D array. first dimension for each trial second dimension for data ex) dict['NSGA2'] = [[pt1,pt2, ...], [pt100,pt101, ...], ...] each pt = [evaluation metric1, metric2, metric3, ...] ref_pt: array. ex) ref_pt = [pt1, pt2, pt3, ...] each pt = [evaluation metric1, metric2, metric3, ...] :param SIR_name: String, SIR program name :param version: int, version of SIR program :return: ''' directory = GLOB.RESULT_DIRECTORY + SIR_name + '/' data = dict() ref_pt = [] for MOEA in GLOB.TRY_ALGORITHM: data_moea = [[] for i in range(GLOB.TRIALS_PER_VERSION)] for i in range(GLOB.TRIALS_PER_VERSION): fname = 'eval_' + SIR_name + '_version' + str(version) + '_' + MOEA + '_trial' + str(i) + '.csv' with open(directory + fname, 'r') as f: f.readline() rdr = csv.reader(f) for line in rdr: for j in range(len(line)): line[j] = float(line[j]) data_moea[i].append(np.array(line)) gene = GA.Gene_Info(None) gene.set_eval(np.array(line)) ref_pt.append(gene) ref_pt = GA.get_pareto(ref_pt)[0] #update reference point data[MOEA] = data_moea for i in range(len(ref_pt)): ref_pt[i] = ref_pt[i].get_eval() return data, ref_pt
def run_NSGA2(SIR_name, version, test_size): evaluator = evaluation.VEval(SIR_name, version, test_size) dim = test_size population = GA.initial_genes(dim, GLOB.POP, version) if GLOB.DEBUG: print('0', len(population)) population_history = [population] for i in range(GLOB.MAX_IT): new_pop = GA.crossover(population, mr=1 / dim) GA.evaluate(new_pop, evaluator) pareto = GA.get_pareto(new_pop) new_pop = select(pareto) population = new_pop population_history.append(population) if GLOB.DEBUG: print(i, len(population)) first_pareto = get_first_pareto(population) #final result return first_pareto
def run_TAEA(SIR_name, version, test_size): evaluator = evaluation.VEval(SIR_name, version, test_size) dim = test_size population = GA.initial_genes(dim, GLOB.POP,version) population_history = [population] CA, DA = [], [] #covergence archive, diversity archive GA.evaluate(population,evaluator) if GLOB.DEBUG: print('0', 0) for i in range(GLOB.MAX_IT): CA, DA = collect_non_dominated(population,CA,DA) #print(len(CA), len(DA)) population = new_crossover(CA,DA,GLOB.CROSSOVER_RATE,1/test_size) GA.evaluate(population,evaluator) if GLOB.DEBUG: print(i,len(CA+DA), 'covergence archive size', len(CA), 'divergence archive size', len(DA)) return CA+DA
def run_TAEA(input_fname): modify = modifier.modify_testcase(input_fname) dim = modify.get_datasize() population = GA.initial_genes(dim, GLOB.POP) population_history = [population] CA, DA = [], [] #covergence archive, diversity archive GA.evaluate(population,modify) for i in range(GLOB.MAX_IT): collect_non_dominated(population,CA,DA) new_pop = GA.crossover(CA+DA) GA.evaluate(new_pop,modify)
def new_crossover(CA,DA): ratio = GLOB.CA_DA_RATIO new_pop = [] for i in range(GLOB.POP): p1,p2 = None,None if len(DA) != 0: rand_num = random.random() if rand_num < ratio*ratio: p1,p2 = random.sample(CA,2) elif rand_num < 2*ratio-ratio*ratio: p1 = random.sample(CA,1)[0] p2 = random.sample(DA,1)[0] else: p1,p2 = random.sample(DA,2) else: p1,p2 = random.sample(CA,2) child = GA.PMX(p1,p2) new_pop.append(child) return new_pop