def save_visualization_results_single(problem, solution, best_fit, name_model, name_paras, path_results): from model.fitness import Fitness from utils.schedule_util import matrix_to_schedule from utils.visual.bar import bar_chart_2d path_png = f'{path_results}/visualization/png' path_pdf = f'{path_results}/visualization/pdf' Path(path_png).mkdir(parents=True, exist_ok=True) Path(path_pdf).mkdir(parents=True, exist_ok=True) file_name = f'{path_results}/{name_paras}' fit_obj = Fitness(problem) schedule = matrix_to_schedule(problem, solution) power = fit_obj.calc_power_consumption(schedule) latency = fit_obj.calc_latency(schedule) cost = fit_obj.calc_cost(schedule) fn_2d_power = f'/{file_name}-2d-power' fn_2d_latency = f'/{file_name}-2d-latency' fn_2d_cost = f'/{file_name}-2d-cost' fn_2d_fit = f'/{file_name}-2d-fit' bar_chart_2d([best_fit], [f'fitness: {Config.METRICS}'], [name_model], ["red"], fn_2d_fit, [path_png, path_pdf], [".png", ".pdf"]) bar_chart_2d([power], [f'Power Consumption'], [name_model], ["red"], fn_2d_power, [path_png, path_pdf], [".png", ".pdf"]) bar_chart_2d([latency], [f'Service Latency'], [name_model], ["red"], fn_2d_latency, [path_png, path_pdf], [".png", ".pdf"]) bar_chart_2d([cost], [f'Monetary Cost'], [name_model], ["red"], fn_2d_cost, [path_png, path_pdf], [".png", ".pdf"])
def evolve2(self, pop: list, pop_archive: list, fe_mode=None, epoch=None, g_best=None): # Generating new population with double size using ALO equations # random_solution = pop_archive[0] random_solution = pop_archive[randint(0, len(pop_archive))] for i in range(0, self.pop_size): random_antlion_pos = random_solution[self.ID_POS].flatten() dim = len(random_antlion_pos) global_best_pos = g_best[self.ID_POS].flatten() RA = self.random_walk_around_antlion(epoch, self.epoch, self.lb, self.ub, random_antlion_pos, dim) RE = self.random_walk_around_antlion(epoch, self.epoch, self.lb, self.ub, global_best_pos, dim) child = (RA[epoch] + RE[epoch]) / 2 child = reshape(child, self.problem["shape"]) while True: matrix = uniform() * child matrix = self.amend_position_random(matrix) schedule = matrix_to_schedule(self.problem, matrix) if schedule.is_valid(): fitness = self.Fit.fitness(schedule) idx = uuid4().hex break pop[i] = [idx, matrix, fitness] return pop
def create_solution(self): while True: matrix = uniform(self.lb, self.ub, self.problem["shape"]) schedule = matrix_to_schedule(self.problem, matrix) if schedule.is_valid(): fitness = self.Fit.fitness(schedule) break return [matrix, fitness] # [solution, fit]
def evolve(self, pop=None, fe_mode=None, epoch=None, g_best=None): a = 2 - 2 * epoch / (self.epoch - 1) # linearly decreased from 2 to 0 for i in range(self.pop_size): r = random() A = 2 * a * r - a C = 2 * r l = uniform(-1, 1) if uniform() < self.p: if abs(A) < 1: while True: child = g_best[self.ID_POS] - A * abs( C * g_best[self.ID_POS] - pop[i][self.ID_POS]) schedule = matrix_to_schedule(self.problem, child) if schedule.is_valid(): fitness = self.Fit.fitness(schedule) break else: while True: id_rand = choice( list(set(range(0, self.pop_size)) - {i})) # select random 1 position in pop child = pop[id_rand][self.ID_POS] - A * abs( C * pop[id_rand][self.ID_POS] - pop[i][self.ID_POS]) schedule = matrix_to_schedule(self.problem, child) if schedule.is_valid(): fitness = self.Fit.fitness(schedule) break else: while True: D1 = abs(g_best[self.ID_POS] - pop[i][self.ID_POS]) child = D1 * exp(self.b * l) * cos( 2 * pi * l) + g_best[self.ID_POS] schedule = matrix_to_schedule(self.problem, child) if schedule.is_valid(): fitness = self.Fit.fitness(schedule) break pop[i] = [child, fitness] if fe_mode is None: return pop else: counter = 2 * self.pop_size # pop_new + pop_mutation operations return pop, counter
def create_solution(self): while True: pos = uniform(self.lb, self.ub, self.problem["shape"]) schedule = matrix_to_schedule(self.problem, pos) if schedule.is_valid(): fitness = self.Fit.fitness(schedule) vel = uniform(self.lb, self.ub, self.problem["shape"]) break return [pos, fitness, vel, pos, fitness]
def crossover(self, dad, mom, p_c): if random() < p_c: child = (dad[self.ID_POS] + mom[self.ID_POS]) / 2 schedule = matrix_to_schedule(self.problem, child) if schedule.is_valid(): fitness = self.Fit.fitness(schedule) idx = uuid4().hex else: while True: coef = uniform(0, 1) child = coef * dad[self.ID_POS] + (1 - coef) * mom[self.ID_POS] schedule = matrix_to_schedule(self.problem, child) if schedule.is_valid(): fitness = self.Fit.fitness(schedule) idx = uuid4().hex break return [idx, child, fitness] return dad
def make_equilibrium_pool(self, list_equilibrium=None, c_eq5=None): # make equilibrium pool pos_list = [item[self.ID_POS] for item in list_equilibrium] c_mean = mean(pos_list, axis=0) schedule = matrix_to_schedule(self.problem, c_mean) if schedule.is_valid(): fit = self.Fit.fitness(schedule) list_equilibrium.append([c_mean, fit]) else: list_equilibrium.append(c_eq5) return list_equilibrium
def crossover(self, dad, mom): if uniform() < self.p_c: child = (dad[self.ID_POS] + mom[self.ID_POS]) / 2 schedule = matrix_to_schedule(self.problem, child) if schedule.is_valid(): fitness = self.Fit.fitness(schedule) else: while True: coef = uniform(0, 1) child = coef*dad[self.ID_POS] + (1-coef)*mom[self.ID_POS] schedule = matrix_to_schedule(self.problem, child) if schedule.is_valid(): fitness = self.Fit.fitness(schedule) break return [child, fitness] else: if Config.METRICS in Config.METRICS_MAX: return mom if dad[self.ID_FIT] < mom[self.ID_FIT] else dad else: return dad if dad[self.ID_FIT] < mom[self.ID_FIT] else mom
def create_opposition_based_pop(self, pop: list): size = len(pop) pop_opposition = [0 for _ in range(size)] for i in range(size): while True: matrix = self.lb + self.ub - uniform() * pop[i][self.ID_POS] schedule = matrix_to_schedule(self.problem, matrix) if schedule.is_valid(): fitness = self.Fit.fitness(schedule) idx = uuid4().hex break pop_opposition[i] = [idx, matrix, fitness] return pop_opposition
def mutate(self, child, p_m): while True: child_pos = deepcopy(child[self.ID_POS]) rd_matrix = uniform(self.lb, self.ub, self.problem["shape"]) child_pos[rd_matrix < p_m] = 0 rd_matrix_new = uniform(self.lb, self.ub, self.problem["shape"]) rd_matrix_new[rd_matrix >= p_m] = 0 child_pos = child_pos + rd_matrix_new schedule = matrix_to_schedule(self.problem, child_pos) if schedule.is_valid(): fitness = self.Fit.fitness(schedule) idx = uuid4().hex break return [idx, child_pos, fitness]
def mutate(self, pop): for i in range(self.pop_size): while True: child = deepcopy(pop[i][self.ID_POS]) rd_matrix = uniform(self.lb, self.ub, self.problem["shape"]) child[rd_matrix < self.p_m] = 0 rd_matrix_new = uniform(self.lb, self.ub, self.problem["shape"]) rd_matrix_new[rd_matrix >= self.p_m] = 0 child = child + rd_matrix_new schedule = matrix_to_schedule(self.problem, child) if schedule.is_valid(): fitness = self.Fit.fitness(schedule) break pop[i] = [child, fitness] return pop
def save_experiment_results_single(problem, solution, list_fitness, name_paras, time_total, path_results, save_training=True): from model.fitness import Fitness from utils.schedule_util import matrix_to_schedule ## Saving fitness path_results = f'{path_results}/experiment_results' Path(path_results).mkdir(parents=True, exist_ok=True) fit_obj = Fitness(problem) schedule = matrix_to_schedule(problem, solution) power = fit_obj.calc_power_consumption(schedule) latency = fit_obj.calc_latency(schedule) cost = fit_obj.calc_cost(schedule) fitness = fit_obj.fitness(schedule) file_name = f'{path_results}/{name_paras}' experiment_results = array([[power, latency, cost, fitness, time_total]]) df1 = DataFrame(experiment_results) df1.index.name = "Solution" df1.to_csv(f'{file_name}-results.csv', header=["Power", "Latency", "Cost", "Fitness", "Time"], index=True) ## Saving model schedule_object_save_path = open(f'{file_name}-solution.pkl', 'wb') pkl.dump(schedule, schedule_object_save_path) schedule_object_save_path.close() ## Saving training process if save_training: fitness_df = DataFrame(list_fitness) fitness_df.index.name = "epoch" fitness_df.to_csv(f'{file_name}-training.csv', index=True, header=["fitness"])
def evolve(self, pop=None, fe_mode=None, epoch=None, g_best=None): if Config.METRICS in Config.METRICS_MAX: pop_sorted = sorted(pop, key=lambda item: item[self.ID_FIT], reverse=True) else: pop_sorted = sorted(pop, key=lambda item: item[self.ID_FIT]) c_eq_list, c_eq5 = pop_sorted[:4], pop_sorted[4] c_pool = self.make_equilibrium_pool(c_eq_list, c_eq5) t = (1 - epoch / self.epoch) ** (self.a2 * epoch / self.epoch) # Eq. 9 for i in range(0, self.pop_size): while True: child = pop[i][self.ID_POS] c_eq = c_pool[randint(0, len(c_pool))][self.ID_POS] # random selection 1 of candidate from the pool lamda = uniform(0, 1, child.shape) # lambda in Eq. 11 r = uniform(0, 1, child.shape) # r in Eq. 11 f = self.a1 * sign(r - 0.5) * (exp(-lamda * t) - 1.0) # Eq. 11 r1 = uniform() r2 = uniform() # r1, r2 in Eq. 15 gcp = 0.5 * r1 * ones(child.shape) * (r2 >= self.GP) # Eq. 15 g0 = gcp * (c_eq - lamda * pop[i][self.ID_POS]) # Eq. 14 g = g0 * f # Eq. 13 temp = c_eq + (pop[i][self.ID_POS] - c_eq) * f + (g * self.V / lamda) * (1.0 - f) # Eq. 16 child = self.amend_position_random(temp) schedule = matrix_to_schedule(self.problem, child) if schedule.is_valid(): fit = self.Fit.fitness(schedule) break if Config.METRICS in Config.METRICS_MAX: if fit > pop[i][self.ID_FIT]: pop[i] = [child, fit] else: if fit < pop[i][self.ID_FIT]: pop[i] = [child, fit] if fe_mode is None: return pop else: counter = 2 * self.pop_size # pop_new + pop_mutation operations return pop, counter
def evolve(self, pop=None, fe_mode=None, epoch=None, g_best=None): # Update weight after each move count (weight down) w = (self.epoch - epoch) / self.epoch * (self.w_max - self.w_min) + self.w_min for i in range(self.pop_size): while True: v_new = w * pop[i][self.ID_VEL] + self.c_local * uniform() * (pop[i][self.ID_LOCAL_POS] - pop[i][self.ID_POS]) + \ self.c_global * uniform() * (g_best[self.ID_POS] - pop[i][self.ID_POS]) x_new = pop[i][ self. ID_POS] + v_new # Xi(new) = Xi(old) + Vi(new) * deltaT (deltaT = 1) v_new = self.amend_position_random(v_new) x_new = self.amend_position_random(x_new) schedule = matrix_to_schedule(self.problem, x_new) if schedule.is_valid(): fit_new = self.Fit.fitness(schedule) pop[i][self.ID_POS] = x_new pop[i][self.ID_FIT] = fit_new pop[i][self.ID_VEL] = v_new # Update current position, current velocity and compare with past position, past fitness (local best) if Config.METRICS in Config.METRICS_MAX: if fit_new > pop[i][self.ID_LOCAL_FIT]: pop[i][self.ID_LOCAL_POS] = x_new pop[i][self.ID_LOCAL_FIT] = fit_new else: if fit_new < pop[i][self.ID_LOCAL_FIT]: pop[i][self.ID_LOCAL_POS] = x_new pop[i][self.ID_LOCAL_FIT] = fit_new break if fe_mode is None: return pop else: counter = self.pop_size # pop_new + pop_mutation operations return pop, counter
def double_population(self, pop: dict, epoch: int): ## Sort population based on fronts fronts, max_rank = self.fast_non_dominated_sort(pop) pop_new = {} for front in fronts: for stt in front: idx = list(pop.keys())[stt] _idx = uuid4().hex pop_new[_idx] = deepcopy(pop[idx]) pop_new[_idx][self.ID_IDX] = _idx n1, n2 = len(fronts[0]), len(fronts[-1]) if n1 == 0 or n1 == self.pop_size: n1 = int(self.PD * self.pop_size) if n2 == 0 or n2 == self.pop_size: n2 = int(self.SD * self.pop_size) r2 = uniform() # R2 in [0, 1], the alarm value, random value # Using equation (3) update the sparrow’s location; for i in range(0, n1): while True: if r2 < self.ST: x_new = pop_new[list( pop_new.keys())[i]][self.ID_POS] * exp( (epoch + 1) / self.epoch) else: x_new = pop_new[list(pop_new.keys())[i]][ self.ID_POS] + normal() * ones(self.problem["shape"]) x_new = self.amend_position_random(x_new) schedule = matrix_to_schedule(self.problem, x_new) if schedule.is_valid(): fit = self.Fit.fitness(schedule) idx = uuid4().hex break child = [idx, x_new, fit] pop_new[idx] = child idx_best, idx_worst = self.get_current_best_worst(pop_new) current_best, current_worst = pop_new[list( pop_new.keys())[idx_best]], pop_new[list( pop_new.keys())[idx_worst]] # Using equation (4) update the sparrow’s location; for i in range(n1, self.pop_size): while True: if i > int(self.pop_size / 2): x_new = normal() * exp( (current_worst[self.ID_POS] - pop_new[list(pop_new.keys())[i]][self.ID_POS]) / (i + 1)**2) else: x_new = current_best[self.ID_POS] + abs( pop_new[list(pop_new.keys())[i]][self.ID_POS] - current_best[self.ID_POS]) * normal() x_new = self.amend_position_random(x_new) schedule = matrix_to_schedule(self.problem, x_new) if schedule.is_valid(): fit = self.Fit.fitness(schedule) idx = uuid4().hex break child = [idx, x_new, fit] pop_new[idx] = child # Using equation (5) update the sparrow’s location; n2_list = choice(list(range(0, self.pop_size)), n2, replace=False) for i in n2_list: while True: child = pop_new[list(pop_new.keys())[i]] if i in fronts[0]: x_new = current_best[self.ID_POS] + normal() * abs( child[self.ID_POS] - current_best[self.ID_POS]) else: dist = sum( sqrt((child[self.ID_FIT] - current_worst[self.ID_FIT])**2)) x_new = child[self.ID_POS] + uniform(-1, 1) * ( abs(child[self.ID_POS] - current_best[self.ID_POS]) / (dist + self.EPSILON)) x_new = self.amend_position_random(x_new) schedule = matrix_to_schedule(self.problem, x_new) if schedule.is_valid(): fit = self.Fit.fitness(schedule) idx = uuid4().hex break child = [idx, x_new, fit] pop_new[idx] = child return {**pop, **pop_new}
def evolve(self, pop=None, fe_mode=None, epoch=None, g_best=None): # Sorted population in the descending order of the function fitness value if Config.METRICS in Config.METRICS_MAX: pop = sorted(pop, key=lambda item: item[self.ID_FIT]) else: pop = sorted(pop, key=lambda item: item[self.ID_FIT], reverse=True) pop_new = deepcopy(pop) ## Production - Update the worst solution # Eq. 2, 3, 1 a = (1.0 - epoch / self.epoch) * uniform() while True: child = (1 - a) * pop[-1][self.ID_POS] + a * uniform( self.lb, self.ub, pop[-1][self.ID_POS].shape) schedule = matrix_to_schedule(self.problem, child) if schedule.is_valid(): fit = self.Fit.fitness(schedule) break pop_new[0] = [child, fit] ## Consumption for i in range(2, self.pop_size): while True: rand = uniform() # Eq. 4, 5, 6 v1 = normal(0, 1) v2 = normal(0, 1) c = 0.5 * v1 / abs(v2) # Consumption factor j = randint(1, i) ### Herbivore if rand < 1.0 / 3: child = pop[i][self.ID_POS] + c * ( pop[i][self.ID_POS] - pop[0][self.ID_POS]) # Eq. 6 ### Carnivore elif 1.0 / 3 <= rand and rand <= 2.0 / 3: child = pop[i][self.ID_POS] + c * ( pop[i][self.ID_POS] - pop[j][self.ID_POS]) # Eq. 7 ### Omnivore else: r2 = uniform() child = pop[i][self.ID_POS] + c * ( r2 * (pop[i][self.ID_POS] - pop[0][self.ID_POS]) + (1 - r2) * (pop[i][self.ID_POS] - pop[j][self.ID_POS])) child = self.amend_position_random(child) schedule = matrix_to_schedule(self.problem, child) if schedule.is_valid(): fit = self.Fit.fitness(schedule) break pop_new[i] = [child, fit] ## Update old population pop = self.update_old_population(pop, pop_new) ## find current best used in decomposition current_best = self.get_current_best(pop) ## Decomposition ### Eq. 10, 11, 12, 9 for i in range(0, self.pop_size): while True: r3 = uniform() d = 3 * normal(0, 1) e = r3 * randint(1, 3) - 1 h = 2 * r3 - 1 child = current_best[self.ID_POS] + d * ( e * current_best[self.ID_POS] - h * pop[i][self.ID_POS]) child = self.amend_position_random(child) schedule = matrix_to_schedule(self.problem, child) if schedule.is_valid(): fit = self.Fit.fitness(schedule) break pop_new[i] = [child, fit] ## Update old population pop = self.update_old_population(pop, pop_new) if fe_mode is None: return pop else: counter = 2 * self.pop_size # pop_new + pop_mutation operations return pop, counter
def evolve2(self, pop: list, pop_archive: list, fe_mode=None, epoch=None, g_best=None): # Updating population by SSA-equations. pop = self.sort_population(pop) global_best_pos = g_best[self.ID_POS] random_solution = pop_archive[randint(0, len(pop_archive))] dominated_list = self.find_dominates_list(pop) n1_invert = sum(dominated_list) ## number of dominated n1 = int(self.pop_size - n1_invert) ## number of non-dominated -> producers n2 = int(self.SD * self.pop_size) # Using equation (3) update the sparrow’s location; for i in range(0, n1): while True: if uniform( ) < self.ST: # R2 in [0, 1], the alarm value, random value x_new = pop[i][self.ID_POS] * exp((epoch + 1) / self.epoch) else: x_new = pop[i][self.ID_POS] + normal() * ones( self.problem["shape"]) child = self.amend_position_random(x_new) schedule = matrix_to_schedule(self.problem, child) if schedule.is_valid(): fit = self.Fit.fitness(schedule) idx = uuid4().hex break pop[i] = [idx, child, fit] # Using equation (4) update the sparrow’s location; shape = g_best[self.ID_POS].shape for i in range(n1, self.pop_size): while True: if i > int(self.pop_size / 2): x_new = normal() * exp( (random_solution[self.ID_POS] - pop[i][self.ID_POS]) / ((i + 1)**2)) else: # A = sign(uniform(-1, 1, (1, shape[0]*shape[1]))) # A1 = matmul(A.T, inv(matmul(A, A.T))) # A1 = matmul(A1, ones((1, shape[0]*shape[1]))) # temp = reshape(abs(pop[i][self.ID_POS] - global_best_pos), (shape[0] * shape[1])) # temp = matmul(temp, A1) # x_new = global_best_pos + uniform() * reshape(temp, shape) x_new = global_best_pos + normal(0, 1, shape) * abs( pop[i][self.ID_POS] - global_best_pos) child = self.amend_position_random(x_new) schedule = matrix_to_schedule(self.problem, child) if schedule.is_valid(): fit = self.Fit.fitness(schedule) idx = uuid4().hex break pop[i] = [idx, child, fit] ## Using equation (5) update the sparrow’s location; n2_list = choice(list(range(0, self.pop_size)), n2, replace=False) dominated_list = self.find_dominates_list(pop) non_dominated_list = where(dominated_list == 0)[0] for i in n2_list: if i in non_dominated_list: x_new = global_best_pos + normal() * abs(pop[i][self.ID_POS] - global_best_pos) else: dist = sum(sqrt( (pop[i][self.ID_FIT] - g_best[self.ID_FIT])**2)) x_new = pop[i][self.ID_POS] + uniform( -1, 1) * (abs(pop[i][self.ID_POS] - global_best_pos) / (dist + self.EPSILON)) while True: child = self.amend_position_random(x_new) schedule = matrix_to_schedule(self.problem, child) if schedule.is_valid(): fit = self.Fit.fitness(schedule) idx = uuid4().hex break pop[i] = [idx, child, fit] return pop
def evolve(self, pop=None, fe_mode=None, epoch=None, g_best=None): r2 = uniform() # R2 in [0, 1], the alarm value, random value # Using equation (3) update the sparrow’s location; for i in range(0, self.n1): while True: if r2 < self.ST: child = pop[i][self.ID_POS] * exp( (i + 1) / (uniform(self.EPSILON, 1) * self.epoch)) else: child = pop[i][self.ID_POS] + normal() * ones( self.problem["shape"]) child = self.amend_position_random(child) schedule = matrix_to_schedule(self.problem, child) if schedule.is_valid(): fit = self.Fit.fitness(schedule) break pop[i] = self.update_old_solution(pop[i], [child, fit]) child_p = deepcopy(self.get_current_best(pop[:self.n1])) worst = deepcopy(self.get_current_worst(pop)) # Using equation (4) update the sparrow’s location; for i in range(self.n1, self.pop_size): while True: if i > int(self.pop_size / 2): x_new = normal() * exp( (worst[self.ID_POS] - pop[i][self.ID_POS]) / (i + 1)**2) else: x_new = child_p[self.ID_POS] + abs( pop[i][self.ID_POS] - child_p[self.ID_POS]) * normal() x_new = self.amend_position_random(x_new) schedule = matrix_to_schedule(self.problem, x_new) if schedule.is_valid(): fit = self.Fit.fitness(schedule) break pop[i] = self.update_old_solution(pop[i], [x_new, fit]) # Using equation (5) update the sparrow’s location; for i in range(0, self.n2): while True: if Config.METRICS in Config.METRICS_MAX: if pop[i][self.ID_FIT] < g_best[self.ID_FIT]: x_new = g_best[self.ID_POS] + normal() * abs( pop[i][self.ID_POS] - g_best[self.ID_POS]) else: x_new = pop[i][self.ID_POS] + uniform(-1, 1) * \ (abs(pop[i][self.ID_POS] - worst[self.ID_POS]) / (pop[i][self.ID_FIT] - worst[self.ID_FIT] + self.EPSILON)) else: if pop[i][self.ID_FIT] > g_best[self.ID_FIT]: x_new = g_best[self.ID_POS] + normal() * abs( pop[i][self.ID_POS] - g_best[self.ID_POS]) else: x_new = pop[i][self.ID_POS] + uniform(-1, 1) * \ (abs(pop[i][self.ID_POS] - worst[self.ID_POS]) / (pop[i][self.ID_FIT] - worst[self.ID_FIT] + self.EPSILON)) x_new = self.amend_position_random(x_new) schedule = matrix_to_schedule(self.problem, x_new) if schedule.is_valid(): fit = self.Fit.fitness(schedule) break pop[i] = self.update_old_solution(pop[i], [x_new, fit]) if fe_mode is None: return pop else: counter = 2 * self.n1 + self.n2 # pop_new + pop_mutation operations return pop, counter