排列编码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
import pandas as pd import geatpy as ea import numpy as np import random from multiprocessing import Pool class Data: market, market_value = None, None def __init__(self, df, platform, platform_max): self.platform = platform self.platform_max = platform_max self.x = df['交易量'] self.y = df["交易费用"] def getResult(self, choose, average): choose_dict = [{"index": choose[i], "x": self.x[i], "y": self.y[i]} for i in range(len(choose))] choose_dict = sorted(choose_dict, key=lambda x: x["index"]) result = float("inf") for i in range(self.platform): market_value = 0 market = 0 for j in range(average): if choose_dict[i * average + j]["x"] + market > self.platform_max: result = min(result, market_value) break else: market_value += choose_dict[i * average + j]["y"] market += choose_dict[i * average + j]["x"] if market_value <= self.platform_max: result = min(result, market_value) return result # GA 参数设置 class My_nsga(ea.Problem): def __init__(self, dim, df, platform, platform_max): name = 'GA-NET' M = 1 maxormins = [-1] * M Dim = dim varTypes = [1] * Dim lb = [0] * Dim ub = [Dim - 1] * Dim lbin = [1] * Dim ubin = [1] * Dim self.count = 1 self.data = Data(df, platform, platform_max) self.average = int(len(df) / platform) ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb, ub, lbin, ubin) # 目标函数即神经网络返回值 def evalVars(self, Vars): ans = np.zeros(len(Vars), dtype=float).reshape(len(Vars), 1) for i in range(len(Vars)): ans[i][0] = self.data.getResult(Vars[i], self.average) # print(ans.max(axis=0)) return ans # 运行 GA def Run_nsga(dim, df, platform, platform_max, loop_id, ndind=30, maxgen=1500): problem = My_nsga(dim, df, platform, platform_max) myAlgorithm = ea.soea_EGA_templet(problem, ea.Population(Encoding='P', NIND=ndind), MAXGEN=maxgen, logTras=0) # 要得到图把 drawing = 1 saveFlag = 1 res = ea.optimize(myAlgorithm, seed=1, verbose=False, drawing=1, outputMsg=1, drawLog=1, saveFlag=saveFlag, dirName='result{}'.format(loop_id)) if saveFlag: np.savetxt("./result{}/result.csv".format(i), res['Vars'][0], delimiter=",") return res['ObjV'][0][0] if __name__ == "__main__": df = pd.read_excel("data.xlsx", sheet_name=None, engine='openpyxl') # 设置每张表分成的 platform 数量 platforms = [2, 4, 10, 20, 10, 50, 50, 100] # 设置每张表 platform 最大值 platform_maxs = [2000, 1000, 1500, 800, 500, 100, 416, 208] # 设置是否训练表 is_train = [0, 0, 1, 1, 0, 0, 0, 0] values = list(df.values())[:4] pool = Pool(sum(is_train)) for i in range(len(values)): if not is_train[i]: continue # 最后两个参数:种群数量,最大迭代次数 pool.apply_async(Run_nsga, args=(len(values[i]), values[i], platforms[i], platform_maxs[i], i, 500, 600)) pool.close() pool.join() |
格雷编码(选择编码)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
import pandas as pd import geatpy as ea import numpy as np import random from multiprocessing import Pool class Data: market, market_value = None, None def __init__(self, df, platform, platform_max): self.platform = platform self.platform_max = platform_max self.x = df['交易量'] self.y = df["交易费用"] def load(self, choose): self.market = [[] for _ in range(self.platform)] self.market_value = [[] for _ in range(self.platform)] for i in range(len(choose)): if choose[i] != 0: self.market[choose[i] - 1].append(self.x[i]) self.market_value[choose[i] - 1].append(self.y[i]) def getResult(self): if max(list(map(lambda x: sum(x), self.market))) > self.platform_max: return sum(list(map(lambda x: 0 if sum(x) < self.platform_max else self.platform_max - sum(x), self.market))) else: return min(list(map(lambda x: sum(x), self.market_value))) # GA 参数设置 class My_nsga(ea.Problem): def __init__(self, dim, df, platform, platform_max): name = 'GA-NET' M = 1 maxormins = [-1] * M Dim = dim varTypes = [1] * Dim lb = [0] * Dim ub = [platform] * Dim lbin = [1] * Dim ubin = [1] * Dim self.count = 1 self.data = Data(df, platform, platform_max) ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb, ub, lbin, ubin) # 目标函数即神经网络返回值 def evalVars(self, Vars): ans = np.zeros(len(Vars), dtype=float).reshape(len(Vars), 1) for i in range(len(Vars)): self.data.load(Vars[i]) ans[i][0] = self.data.getResult() # print(ans.max(axis=0)) return ans # 得到初始化种群方式1 def getProphet(dim, ndind, df, platform, platform_max): prophet = np.zeros(shape=(ndind, dim), dtype=int) x = df['交易量'] for i in range(ndind): # 使得platform尽可能分配均匀 platforms = [i for i in range(platform + 1)] now = [0 for _ in range(platform)] for j in range(i % dim, dim): if not platforms: platforms = [i for i in range(platform + 1)] choice = random.choice(platforms) platforms.remove(choice) if choice != 0: now[choice - 1] += x[j] if now[choice - 1] < platform_max: prophet[i][j] = choice for j in range(0, i % dim): if not platforms: platforms = [i for i in range(platform + 1)] choice = random.choice(platforms) platforms.remove(choice) if choice != 0: now[choice - 1] += x[j] if now[choice - 1] < platform_max: prophet[i][j] = choice return prophet # 得到初始化种群方式2 def getProphet2(dim, ndind, df, platform, platform_max): prophet = np.zeros(shape=(ndind, dim), dtype=int) x = df['交易量'] for i in range(ndind): # 真随机抽取初始化 now = [0 for _ in range(platform)] for j in range(i % dim, dim): choice = random.choice([i for i in range(platform + 1)]) if choice != 0: now[choice - 1] += x[j] if now[choice - 1] < platform_max: prophet[i][j] = choice for j in range(0, i % dim): choice = random.choice([i for i in range(platform + 1)]) if choice != 0: now[choice - 1] += x[j] if now[choice - 1] < platform_max: prophet[i][j] = choice return prophet # 运行 GA def Run_nsga(dim, df, platform, platform_max, loop_id, ndind=30, maxgen=1500): problem = My_nsga(dim, df, platform, platform_max) myAlgorithm = ea.soea_EGA_templet(problem, ea.Population(Encoding='RI', NIND=ndind), MAXGEN=maxgen, logTras=0) prophet = getProphet(dim, ndind, df, platform, platform_max) # 要得到图把 drawing = 1 saveFlag = 1 res = ea.optimize(myAlgorithm, prophet=prophet, seed=1, verbose=False, drawing=1, outputMsg=1, drawLog=1, saveFlag=saveFlag, dirName='result{}'.format(loop_id)) if saveFlag: np.savetxt("./result{}/result.csv".format(i), res['Vars'][0], delimiter=",") return res['ObjV'][0][0] if __name__ == "__main__": df = pd.read_excel("data.xlsx", sheet_name=None, engine='openpyxl') # 设置每张表分成的 platform 数量 platforms = [2, 4, 10, 20, 10, 50, 50, 100] # 设置每张表 platform 最大值 platform_maxs = [2000, 1000, 1500, 800, 500, 100, 416, 208] # platform_maxs[4] = [100, 200, 300, 400, 500, 500, 600, 700, 800, 900] # 设置是否训练表 # is_train = [1, 1, 1, 1, 1, 1, 1, 1] is_train = [1, 1, 1, 1, 0, 0, 0, 0] result = [] result_value = [] values = list(df.values())[:8] pool = Pool(sum(is_train)) for i in range(len(values)): if not is_train[i]: continue # 最后两个参数:种群数量,最大迭代次数 pool.apply_async(Run_nsga, args=(len(values[i]), values[i], platforms[i], platform_maxs[i], i, 500, 1000)) pool.close() pool.join() # now_value = Run_nsga(len(values[i]), values[i], platforms[i], platform_maxs[i], i, 500, 1000) # result_value.append(now_value) # np.savetxt("result_values.csv", result_value, delimiter=",") |
两个编码方式有差异,我个人认为排列编码会比较好一点,逻辑更加高一些。代码中为EGA模板(即带有精英选择机制的遗传算法),测试下来可能NSGA-ii模板会更优一些,可以在测试的时候选择你想要的算法及结果。data.xlsx