dva*_*val 5 python optimization search
我有一个非常简单的问题,我认为网上可能有解决方案,但我还没有找到。
我有一个(非数学即非分析)函数,它根据来自一组文件/数据库/在线爬行的一组变量 a、b、c、d 计算值 F,我想找到该组使 F 最大化的变量 a、b、c、d。搜索 a、b、c、d 的整个空间是不可行的,并且不可能使用微分/导数,因为 F 不是解析的。我真的很感激我可以使用哪些包/算法的指针,或者只是如何开始。我在网上看到的关于 python 优化的大部分内容似乎都是关于分析/数学函数 (f(x) = x^2 + ...) 而不是更多的非分析问题。
例如:
def F(a,b,c,d):
... a lot of computations from databases, etc using
a,b,c,d that are different float values ...
returns output # output is a float
Run Code Online (Sandbox Code Playgroud)
现在,对于 a,b,c,d 的所有值,其中每个值都有可能的值,假设为 [0, 0.1, 0.2, ... 1.0]。这些值是离散的,我的优化不需要极高的精度。
现在,我想找到一组值 a,b,c,d 给我最高的 F。
哦,我对 F、a、b、c、d 都没有最大化约束。
感谢大家的帮助和评论,我能够找到答案。DEAP 文档非常有帮助,但我还是想分享我的答案以及一些希望对其他人有帮助的评论。
\n\n我使用了此处的 OneMax 示例https://github.com/DEAP/deap/blob/b46dde2b74a3876142fdcc40fdf7b5caaa5ea1f4/examples/ga/onemax.py以及此处的演练: https: //deap.readthedocs.org/en/latest/示例/ga_onemax.html。我发现这两页也非常宝贵,运算符: https: //deap.readthedocs.org/en/latest/tutorials/basic/part2.html#next-step和创建类型: https: //deap.readthedocs.org/en /latest/tutorials/basic/part1.html#creating-types
\n\n所以我的解决方案就在这里(对格式表示歉意,这是我第一次发布长代码并添加注释)。基本上,您真正要做的就是使适应度评估函数(此处eval_Inidividual)成为您要优化的函数 F。您可以通过限制初始化(此处random_initialization)和突变(此处 )时的可能值来限制 F 的 N 个变量/输入中每一个的范围(和分布mutate_inputs)。
最后一点:我使用多处理库使我的代码成为多核(只需两行代码并更改您使用的映射函数即可!!)。在这里阅读更多信息:https ://deap.readthedocs.org/en/default/tutorials/distribution.html
\n\n代码(阅读我的评论以获取更多解释):
\n\nimport random\n\nfrom deap import base\nfrom deap import creator\nfrom deap import tools\n\nstart_clock = time.clock()\n\n\nNGEN = 100 # number of generations to run evolution on\npop_size = 10000 # number of individuals in the population. this is the number of points in the N-dimensional space you start within\nCXPB = 0.5 # probability of cross-over (reproduction) to replace individuals in population by their offspring\nMUTPB = 0.2 # probability of mutation\nmutation_inside = 0.05 # prob mutation within individual\nnum_cores = 6\nN = 8 # the number of variables you are trying to optimize over. you can limit the range (and distribtuion) of each of them by limiting their possible values at initialization and mutation.\n\n\ndef eval_Inidividual(individual):\n # this code runs on your individual and outputs the \'fitness\' of the individual\n\ndef mutate_inputs(individual, indpb):\n # this is my own written mutation function that takes an individual and changes each element in the tuple with probability indpb \n # there are many great built in such mutation functions\n\ndef random_initialization():\n # this creates each individual with an N-tuple where N is the number of variables you are optimizing over\n\ncreator.create("FitnessMax", base.Fitness, weights=(-1.0,)) # negative if trying to minimize mean, positive if trying to maximize sharpe. can be a tuple if you are trying to maximize/minimize over several outputs at the same time e.g. maximize mean, minimize std for fitness function that returns (mean, std) would need you to use (1.0, -1.0)\ncreator.create("Individual", list, fitness=creator.FitnessMax)\n\ntoolbox = base.Toolbox()\n# Attribute generator\ntoolbox.register("attr_floatzzz", random_initialization) # i call it attr_floatzzz to make sure you know you can call it whatever you want.\n# Structure initializers\ntoolbox.register("individual", tools.initRepeat, creator.Individual, \n toolbox.attr_floatzzz, N) # N is the number of variables in your individual e.g [.5,.5,.5,.5,.1,100] that get \n# fed to your fitness function evalOneMax\ntoolbox.register("population", tools.initRepeat, list, toolbox.individual)\n\nimport multiprocessing as mp\n\npool = mp.Pool(processes=num_cores)\ntoolbox.register("map", pool.map) # these 2 lines allow you to run the computation multicore. You will need to change the map functions everywhere to toolbox.map to tell the algorithm to use a multicored map\n\n# Operator registering\ntoolbox.register("evaluate", eval_Inidividual)\ntoolbox.register("mate", tools.cxTwoPoint)\ntoolbox.register("mutate", mutate_inputs, indpb = mutation_inside)\ntoolbox.register("select", tools.selTournament, tournsize=3)\n\n\ndef main():\n# random.seed(64)\n\n pop = toolbox.population(n=pop_size) # these are the different individuals in this population, \n # each is a random combination of the N variables\n\n print("Start of evolution")\n\n # Evaluate the entire population\n fitnesses = list(toolbox.map(toolbox.evaluate, pop))\n for ind, fit in zip(pop, fitnesses):\n ind.fitness.values = fit #this runs the fitness (min mean on each of the individuals)\n\n# print(" Evaluated %i individuals" % len(pop))\n\n # Begin the evolution\n for g in range(NGEN):\n print("-- Generation %i --" % g)\n f.write("-- Generation %i --\\n" % g)\n# f.write("-- Generation %i --\\n" % g)\n# g = open(\'GA_generation.txt\',\'w\')\n# g.write("-- Generation %i --" % g)\n# g.close()\n\n # Select the next generation individuals\n offspring = toolbox.select(pop, len(pop)) # this selects the best individuals in the population\n # Clone the selected individuals\n offspring = list(toolbox.map(toolbox.clone, offspring)) #ensures we don\xe2\x80\x99t own a reference to the individuals but an completely independent instance.\n\n # Apply crossover and mutation on the offspring\n for child1, child2 in zip(offspring[::2], offspring[1::2]): #this takes all the odd-indexed and even-indexed pairs child1, child2 and mates them\n if random.random() < CXPB:\n toolbox.mate(child1, child2)\n del child1.fitness.values\n del child2.fitness.values\n\n for mutant in offspring:\n if random.random() < MUTPB:\n toolbox.mutate(mutant)\n del mutant.fitness.values\n\n # Evaluate the individuals with an invalid fitness\n invalid_ind = [ind for ind in offspring if not ind.fitness.valid]\n fitnesses = toolbox.map(toolbox.evaluate, invalid_ind)\n for ind, fit in zip(invalid_ind, fitnesses):\n ind.fitness.values = fit\n\n# print(" Evaluated %i individuals" % len(invalid_ind))\n\n # The population is entirely replaced by the offspring\n pop[:] = offspring\n\n # Gather all the fitnesses in one list and print the stats\n fits = [ind.fitness.values[0] for ind in pop]\n\n# length = len(pop)\n# mean = sum(fits) / length\n# sum2 = sum(x*x for x in fits)\n# std = abs(sum2 / length - mean**2)**0.5\n\n print(" Min %s" % min(fits))\n# print(" Max %s" % max(fits))\n# print(" Avg %s" % mean)\n# print(" Std %s" % std)\n\n print("-- End of (successful) evolution --")\n\n best_ind = tools.selBest(pop, 1)[0]\n print("Best individual is %s with mean %s" % (best_ind, \n best_ind.fitness.values[0])\n\n done = time.clock() - start_clock # the clock doens\'t work on the multicored version. I have no idea how to make it work :)\n print "time taken: ", done, \'seconds\'\n\n\nif __name__ == "__main__":\n main()\nRun Code Online (Sandbox Code Playgroud)\n\nps:时钟在多核版本上不起作用。我不知道如何让它发挥作用:)
\n| 归档时间: |
|
| 查看次数: |
974 次 |
| 最近记录: |