def run(self, max_iter=None): self.max_iter = max_iter or self.max_iter # max_iter 迭代次数,终止条件设置 for i in range(self.max_iter): self.mutation() self.crossover() self.selection() # 记录当前迭代最好的解 generation_best_index = self.COST.argmin() self.generation_best_add_money.append( self.add_money_pop[generation_best_index, :, :].copy()) self.generation_best_COST.append(self.COST[generation_best_index]) self.all_history_COST.append(self.COST) print('第{}次迭代结束,共{}次迭代'.format(i, self.max_iter)) print("-------------------------------------") print("当前最小的COST为:{:.2f}".format(self.generation_best_COST[-1])) # 寻找全局最优解 global_best_index = np.array(self.generation_best_COST).argmin() global_best_add_money = ( self.generation_best_add_money[global_best_index] / 10000 + 0.5).astype(int) * 10000 global_best_COST = ATMData(self.DATA, global_best_add_money).update_COST() return global_best_add_money, global_best_COST
def selection(self): ''' 选择较好的基因遗传下去 :return: 新一轮的种群 ''' COST_X = np.zeros(self.pop_size) COST_U = np.zeros(self.pop_size) for i in range(self.pop_size): COST_X[i] = ATMData(self.DATA, self.add_money_pop[i, :, :]).update_COST() COST_U[i] = ATMData(self.DATA, self.U[i, :, :]).update_COST() update = COST_U < COST_X self.add_money_pop[update, :, :] = self.U[update, :, :].copy() self.COST = np.where(COST_X < COST_U, COST_X, COST_U) return self.add_money_pop, self.COST
def cal_y(self): # calculate y for every x in X self.Y = np.zeros(self.pop) # self.Y = self.func(self.X).reshape(-1, 1) for i in range(self.pop): self.Y[i] = ATMData(self.DATA, self.X[i, :, :]).update_COST() self.Y = np.around(self.Y, decimals=2) return self.Y
def create_pop(self): ''' 创建size = self.pop的初始数组 加钞的原则按照ML原则来加,取加钞范围内的整数 :return: 初始种群 ''' # X 的维度 是 ATM_number * days 所以 V 的维度也是这样的 self.add_money_pop = np.zeros((self.pop, self.DATA.ATM_number, self.DATA.days), dtype=int) # X # V 的初始化 # self.X = np.random.uniform(low=self.lb, high=self.ub, size=(self.pop, self.dim)) self.add_v_pop = np.zeros((self.pop, self.DATA.ATM_number, self.DATA.days), dtype=int) # V for i in range(self.pop): add_money_data = np.zeros((self.DATA.ATM_number, self.DATA.days), dtype=int) # 初始化 V # self.V = np.random.uniform(low=-v_high, high=v_high, size=(self.pop, self.dim)) # add_v_data = np.zeros((self.DATA.ATM_number, self.DATA.days), dtype=int) # 这里的速度需要重新设置初始值 v_high = self.ub - self.lb add_v_data = np.random.uniform(low=-v_high, high=v_high, size=(self.DATA.ATM_number, self.DATA.days)) for t in range(self.DATA.days): add_money_data[:, t] = self.xlb + \ np.random.random(self.DATA.ATM_number) * (self.xub - self.xlb) # v_high = self.ub - self.lb # self.V = np.random.uniform(low=-v_high, high=v_high, size=(self.pop, self.dim)) # add V data self.ub - self.lb V 的值有正有负数 # add_v_data[:, t] = self.lb + \ # np.random.random(self.DATA.ATM_number) * (self.ub - self.lb) # add_money_data[:, t] = self.lb + np.random.randint(0, 121, self.DATA.ATM_number) * 10000 self.add_money_pop[i, :, :] = add_money_data # update V self.add_v_pop[i, :, :] = add_v_data # cal fitness 只需要 X 的值就够了,不需要 V 的值 self.COST[i] = ATMData(self.DATA, self.add_money_pop[i, :, :]).update_COST() generation_best_index = self.COST.argmin() self.generation_best_add_money = self.add_money_pop[generation_best_index, :, :].copy() self.generation_best_COST = self.COST[generation_best_index] # 第一次这里要更新当前的历史最佳值 第一次的历史最佳就是第一次的最佳 self.history_best_add_money = self.add_money_pop[generation_best_index, :, :].copy() self.history_best_COST = self.COST[generation_best_index] # 记录所有的历史最佳 COST 值 self.all_history_COST.append(self.COST.copy()) return self.add_money_pop
def cal_y(self): # calculate y for every x in X # self.Y = self.func(self.X).reshape(-1, 1) # return self.Y # self.Y = self.func(self.X).reshape(-1, 1) # return self.Y COST_X = np.zeros(self.pop_size) for i in range(self.pop_size): COST_X[i] = ATMData(self.DATA, self.add_money_pop[i, :, :]).update_COST() return self.COST
def create_pop(self): ''' 创建size = self.pop_size的初始数组 加钞的原则按照ML原则来加,取加钞范围内的整数 :return: 初始种群 ''' # X self.add_money_pop = np.zeros( (self.pop_size, self.DATA.ATM_number, self.DATA.days), dtype=int) # 对于每个种群,计算 COST,并更新最小下标,最小的代价 for i in range(self.pop_size): # 初始值 add_money_data = np.zeros((self.DATA.ATM_number, self.DATA.days), dtype=int) # 随机化初始值,得到第一代随机值 for t in range(self.DATA.days): add_money_data[:, t] = self.lb + \ np.random.random(self.DATA.ATM_number) * (self.ub - self.lb) # add_money_data[:, t] = self.lb + np.random.randint(0, 121, self.DATA.ATM_number) * 10000 self.add_money_pop[i, :, :] = add_money_data ## 适应度函数计算 self.COST[i] = ATMData(self.DATA, self.add_money_pop[i, :, :]).update_COST() generation_best_index = self.COST.argmin() # 选择 COST 最小的下标 self.generation_best_add_money.append(self.add_money_pop[ generation_best_index, :, :].copy()) ## 得到 pBestX self.generation_best_COST.append( self.COST[generation_best_index]) ## 得到 pBestY self.all_history_COST.append(self.COST) ## 当代的最优值加入到 最优值历史表中 return self.add_money_pop
def fitness(self, x, limit=np.Infinity): x = x.reshape((self.data.ATM_number, self.data.days)) # 不建议硬编码 return ATMData(self.data, x).update_COST()
def update(self): ''' 计算 COST 值,并更新 pbest gbest :return: ''' for i in range(self.pop): # 迭代所有种群,计算 COST 值 for t in range(self.DATA.days): # cal fitness 只需要 X 的值就够了,不需要 V 的值 self.COST[i] = ATMData(self.DATA, self.add_money_pop[i, :, :]).update_COST() generation_best_index = self.COST.argmin() # 当前代中最小值对应的下标 # 这里是更新,不是添加 # pBest[i] 表示的是 第 i 个个体截止当前带的历史最右值 gBest ,某一代节点,所有的种群中只要一个是 gBest self.generation_best_add_money = self.add_money_pop[generation_best_index, :, :].copy() self.generation_best_COST = self.COST[generation_best_index].copy() # 第一次这里要更新当前的历史最佳值 第一次的历史最佳就是第一次的最佳 # 更新历史最佳要进行比较之后加入 self.history_best_add_money = self.add_money_pop[generation_best_index, :, :].copy() self.history_best_COST = self.COST[generation_best_index].copy # 当前的最佳值加入到历史最佳中 self.all_history_COST.append(self.COST[generation_best_index].copy()); def update_pbest(self): ''' personal best :return: ''' # self.pbest_x = np.where(self.pbest_y > self.Y, self.X, self.pbest_x) # self.pbest_y = np.where(self.pbest_y > self.Y, self.Y, self.pbest_y) self.generation_best_add_money = np.where(self.generation_best_COST > self.COST, self.add_money_pop, self.generation_best_add_money) self.generation_best_COST = np.where(self.generation_best_COST > self.COST, self.COST, self.generation_best_COST) def update_gbest(self): ''' global best :return: ''' # if self.gbest_y > self.Y.min(): # self.gbest_x = self.X[self.Y.argmin(), :].copy() # self.gbest_y = self.Y.min() if self.history_best_COST > self.COST.min(): self.history_best_add_money = self.add_money_pop[self.COST.argmin(), :].copy() self.history_best_COST = self.COST.min() def recorder(self): if not self.record_mode: return self.record_value['X'].append(self.add_money_pop) self.record_value['V'].append(self.add_v_pop) self.record_value['Y'].append(self.COST) def run(self, max_iter=None): self.max_iter = max_iter or self.max_iter for iter_num in range(self.max_iter): self.update_V() self.recorder() self.update_X() self.cal_y() self.update_pbest() self.update_gbest() # 记录当前迭代最好的解 generation_best_index = self.COST.argmin() self.generation_best_add_money.append(self.add_money_pop[generation_best_index, :, :].copy()) self.generation_best_COST.append(self.COST[generation_best_index]) self.all_history_COST.append(self.COST) print('第{}次迭代结束,共{}次迭代'.format(iter_num, self.max_iter)) print("-------------------------------------") print("当前最小的COST为:{:.2f}".format(self.generation_best_COST[-1])) # 寻找全局最优解 global_best_index = np.array(self.generation_best_COST).argmin() global_best_add_money = (self.generation_best_add_money[global_best_index] / 10000 + 0.5).astype(int) * 10000 global_best_COST = ATMData(self.DATA, global_best_add_money).update_COST() return global_best_add_money, global_best_COST