zoukankan      html  css  js  c++  java
  • deap实战_2017中国数学建模大赛_B题_第二题

    简介

    补充:本例子仅仅是之前deap类库的一个实战例子,所以先别问我数学建模的事情,我暂时不想回答(还有为毛踩我文章…..我本来就不是写数学建模的……╮(╯▽╰)╭)(2017/10/31)

    原问题是给出一个定价策略,证明其相较于原来定价策略的优点.

    那么首先我们第一题第二问得到了一个 价格-完成率 函数,此时我们需要的是给出一个新的定价函数,并利用遗传算法得到最佳参数.

    思路

    1. 编码–>我们需要编码的是定价函数的参数
    2. 评价函数—->将编码输入的定价函数得到价格,然后将价格输入之前得到的 价格-完成率 函数得到完成率
    3. 求解的目标应当是最大化完成率
    4. 为了控制成本需要对价格进行一定的限制,避免为了提高完成率,而过高定价
    5. 阅读提示,建议阅读该部分前,阅读该基础文章http://blog.csdn.net/fontthrone/article/details/78253230

    Types

    import random
    
    from deap import base
    from deap import creator
    from deap import tools
    
    import time
    
    ThresholdValue = 28.6670026583
    
    creator.create("FitnessMax", base.Fitness, weights=(1.0,))  # 定义最大化适应度
    creator.create("Individual", list, fitness=creator.FitnessMax)  # 这里的list种群的数据类型
    
    toolbox = base.Toolbox()
    
    # Attribute generator: define 'attr_bool' to be an attribute ('gene')
    #                      which corresponds to integers sampled uniformly
    #                      from the range [0,1] (i.e. 0 or 1 with equal
    #                      probability)
    
    
    toolbox.register("attr_bool", random.random)  # 包含了0,1的随机整数,初始化种群
    
    # Structure initializers: define 'individual' to be an individual
    #                         consisting of 100 'attr_bool' elements ('genes')
    toolbox.register("individual", tools.initRepeat, creator.Individual,
                     toolbox.attr_bool, 5)
    
    # define the population to be a list of 'individual's
    toolbox.register("population", tools.initRepeat, list, toolbox.individual)
    

    ReadData

    读取数据,为之后的计算做准备

    
    import pandas as pd
    
    df2 = pd.read_csv('/home/fonttian/Data/MM2017/db.csv')
    
    npones = df2['npones']
    level = df2['level']
    length = df2['length']
    MiDu = df2['MiDu']
    npjt = df2['npjt']
    listlen = df2['listlen']
    price = df2['price']
    

    定义评价函数(适应度函数)

    
    def evalOneMax(individual):
        newPrice = (individual[0] - 0.5) * npones * 20 + (individual[1] - 0.5) * length * 20 + (individual[2] - 0.5) * MiDu * 20 + (individual[3] - 0.5) * level * 20 + (individual[4]) * 100 +listlen * 65.7
        # npones,nplength,npMiDuList3
        w2 = [-0.01633732, 0.83539635, -0.06544261, -0.00280863]
        xjb = length * w2[0] + level * w2[1] + MiDu * w2[2] + npjt * w2[3]
        xjb = xjb * newPrice
        sums = 0
        for i in range(len(xjb)):
            # yuzhi = 28.6670026583
            # if xjb[i] >= yuzhi and newPrice[i] <= price[i] *1.1: # 608
            # if xjb[i] >= yuzhi: # 655
            # yuzhi = 0.474373718686
    
            if xjb[i] >= ThresholdValue and sum(newPrice) <= 57707.5 * 1.3: # 655
                sums += 1
            else:
                pass
    
        return sums, # 注意最后的 , 该文件中必须要有,不然会报错

    注册其他参数(Operator registration)

    # ---------------------Operator registration---------------------
    toolbox.register("evaluate", evalOneMax)
    toolbox.register("mate", tools.cxTwoPoint)
    toolbox.register("mutate", tools.mutFlipBit, indpb=0.05)
    toolbox.register("select", tools.selTournament, tournsize=3)

    设计运行程序,获取我们想要的结果

    def main():
        random.seed(64)
        # hash(64)is used
    
        # random.seed方法的作用是给随机数对象一个种子值,用于产生随机序列。
        # 对于同一个种子值的输入,之后产生的随机数序列也一样。
        # 通常是把时间秒数等变化值作为种子值,达到每次运行产生的随机系列都不一样
    
        # create an initial population of 300 individuals (where
        # each individual is a list of integers)
        pop = toolbox.population(n=300)  # 定义300个个体的种群
    
        # CXPB  is the probability with which two individuals
        #       are crossed
        #
        # MUTPB is the probability for mutating an individual
        #
        # NGEN  is the number of generations for which the
        #       evolution runs   迭代次数
        CXPB, MUTPB, NGEN = 0.5, 0.2, 100
    
        print("Start of evolution")
    
        # Evaluate the entire population
        fitnesses = list(map(toolbox.evaluate, pop))
        # for ind, fit in zip(pop, fitnesses):
        #     ind.fitness.values = fit
    
        print("  Evaluated %i individuals" % len(pop))  # 这时候,pop的长度还是300呢
        print("  迭代 %i 次" % NGEN)
    
        t1 = time.clock()
        # Begin the evolution      开始进化了哈!!!注意注意注意!就是一个for循环里了!NGEN次--代数
        for g in range(NGEN):
            if g % 10 == 0:
                print("-- Generation %i --" % g)
    
            # Select the next generation individuals
            offspring = toolbox.select(pop, len(pop))
            # Clone the selected individuals
            offspring = list(map(toolbox.clone, offspring))
    
            # Apply crossover and mutation on the offspring
            for child1, child2 in zip(offspring[::2], offspring[1::2]):
    
                # cross two individuals with probability CXPB
                if random.random() < CXPB:
                    toolbox.mate(child1, child2)
    
                    # fitness values of the children
                    # must be recalculated later
                    del child1.fitness.values
                    del child2.fitness.values
    
            for mutant in offspring:
    
                # mutate an individual with probability MUTPB
                if random.random() < MUTPB:
                    toolbox.mutate(mutant)
                    del mutant.fitness.values
    
            # Evaluate the individuals with an invalid fitness
            invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
            fitnesses = map(toolbox.evaluate, invalid_ind)
            for ind, fit in zip(invalid_ind, fitnesses):
                ind.fitness.values = fit
    
            # print("  Evaluated %i individuals" % len(invalid_ind))
    
            # The population is entirely replaced by the offspring
            pop[:] = offspring
    
            # Gather all the fitnesses in one list and print the stats
            fits = [ind.fitness.values[0] for ind in pop]
    
            length = len(pop)
            mean = sum(fits) / length
            sum2 = sum(x * x for x in fits)
            std = abs(sum2 / length - mean ** 2) ** 0.5
    
            # print("  Min %s" % min(fits))
            # print("  Max %s" % max(fits))
            # print("  Avg %s" % mean)
            # print("  Std %s" % std)
    
        print("-- End of (successful) evolution --")
    
        best_ind = tools.selBest(pop, 1)[0]
        print("Best individual is %s, %s" % (best_ind, best_ind.fitness.values))
    
        print('预测数据')
        # PevalOneMax([0.6222847026584997, 0.9952779203368345, 0.10901692485431957, 0.8966275594961192, 0.9692993203252058])
        print('该次遗传算法的出的最好的参数的通过数:')
        PevalOneMax(best_ind)
    
        print('出题方给的定价规律的预测通过数',TevalOneMax())
        t2 = time.clock()
        print(t2 - t1)

    全部代码

    # - * - coding: utf - 8 -*-
    # 作者:田丰(FontTian)
    # 创建时间:'2017/9/17'
    #    This file is part of DEAP.
    #
    #    DEAP is free software: you can redistribute it and/or modify
    #    it under the terms of the GNU Lesser General Public License as
    #    published by the Free Software Foundation, either version 3 of
    #    the License, or (at your option) any later version.
    #
    #    DEAP is distributed in the hope that it will be useful,
    #    but WITHOUT ANY WARRANTY; without even the implied warranty of
    #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    #    GNU Lesser General Public License for more details.
    #
    #    You should have received a copy of the GNU Lesser General Public
    #    License along with DEAP. If not, see <http://www.gnu.org/licenses/>.
    
    
    #    example which maximizes the sum of a list of integers
    #    each of which can be 0 or 1
    
    import random
    
    from deap import base
    from deap import creator
    from deap import tools
    
    import time
    
    ThresholdValue = 28.6670026583
    
    creator.create("FitnessMax", base.Fitness, weights=(1.0,))  # 定义最大化适应度
    creator.create("Individual", list, fitness=creator.FitnessMax)  # 这里的list种群的数据类型
    
    toolbox = base.Toolbox()
    
    # Attribute generator: define 'attr_bool' to be an attribute ('gene')
    #                      which corresponds to integers sampled uniformly
    #                      from the range [0,1] (i.e. 0 or 1 with equal
    #                      probability)
    
    
    toolbox.register("attr_bool", random.random)  # 包含了0,1的随机整数,初始化种群
    
    # Structure initializers: define 'individual' to be an individual
    #                         consisting of 100 'attr_bool' elements ('genes')
    toolbox.register("individual", tools.initRepeat, creator.Individual,
                     toolbox.attr_bool, 5)
    
    # define the population to be a list of 'individual's
    toolbox.register("population", tools.initRepeat, list, toolbox.individual)
    
    import pandas as pd
    
    df2 = pd.read_csv('/home/fonttian/Data/MM2017/db.csv')
    
    npones = df2['npones']
    level = df2['level']
    length = df2['length']
    MiDu = df2['MiDu']
    npjt = df2['npjt']
    listlen = df2['listlen']
    price = df2['price']
    
    
    def evalOneMax(individual):
        newPrice = (individual[0] - 0.5) * npones * 20 + (individual[1] - 0.5) * length * 20 + (individual[2] - 0.5) * MiDu * 20 + (individual[3] - 0.5) * level * 20 + (individual[4]) * 100 +listlen * 65.7
        # npones,nplength,npMiDuList3
        w2 = [-0.01633732, 0.83539635, -0.06544261, -0.00280863]
        xjb = length * w2[0] + level * w2[1] + MiDu * w2[2] + npjt * w2[3]
        xjb = xjb * newPrice
        sums = 0
        for i in range(len(xjb)):
            # yuzhi = 28.6670026583
            # if xjb[i] >= yuzhi and newPrice[i] <= price[i] *1.1: # 608
            # if xjb[i] >= yuzhi: # 655
            # yuzhi = 0.474373718686
    
            if xjb[i] >= ThresholdValue and sum(newPrice) <= 57707.5 * 1.3: # 655
                sums += 1
            else:
                pass
    
        return sums,
    
    def PevalOneMax(individual):
        print((individual[0] - 0.5) * 20, (individual[1] - 0.5) * 20, (individual[2] - 0.5) * 20, (individual[3] - 0.5) * 20, (individual[4]) * 100)
        newPrice = (individual[0] - 0.5) * npones * 20 + (individual[1] - 0.5) * length * 20 + (individual[2] - 0.5) * MiDu * 20 + (individual[3] - 0.5) * level * 20 + (individual[4]) * 100
        w2 = [-0.01633732, 0.83539635, -0.06544261, -0.00280863]
        xjb = length * w2[0] + level * w2[1] + MiDu * w2[2] + npjt * w2[3]
        xjb = xjb * newPrice
        sums = 0
        for i in range(len(xjb)):
            if xjb[i] >= ThresholdValue:
                sums += 1
            else:
                pass
    
        print(sums)
        print("新的总价:",sum(newPrice),'旧的总价:',sum(price))
    
        return sums,
    
    # ---------------------Operator registration---------------------
    toolbox.register("evaluate", evalOneMax)
    toolbox.register("mate", tools.cxTwoPoint)
    toolbox.register("mutate", tools.mutFlipBit, indpb=0.05)
    toolbox.register("select", tools.selTournament, tournsize=3)
    
    
    def TevalOneMax():
        # 原定价模型的通过率
        w2 = [-0.01633732, 0.83539635, -0.06544261, -0.00280863]
        xjb = length * w2[0] + level * w2[1] + MiDu * w2[2] + npjt * w2[3]
        xjb = xjb * price
        sum = 0
        for i in range(len(xjb)):
            if xjb[i] >= ThresholdValue:
                sum += 1
            else:
                pass
        return sum
    
    # --------------------- main ---------------------
    
    def main():
        random.seed(64)
        # hash(64)is used
    
        # random.seed方法的作用是给随机数对象一个种子值,用于产生随机序列。
        # 对于同一个种子值的输入,之后产生的随机数序列也一样。
        # 通常是把时间秒数等变化值作为种子值,达到每次运行产生的随机系列都不一样
    
        # create an initial population of 300 individuals (where
        # each individual is a list of integers)
        pop = toolbox.population(n=300)  # 定义300个个体的种群
    
        # CXPB  is the probability with which two individuals
        #       are crossed
        #
        # MUTPB is the probability for mutating an individual
        #
        # NGEN  is the number of generations for which the
        #       evolution runs   迭代次数
        CXPB, MUTPB, NGEN = 0.5, 0.2, 100
    
        print("Start of evolution")
    
        # Evaluate the entire population
        fitnesses = list(map(toolbox.evaluate, pop))
        # for ind, fit in zip(pop, fitnesses):
        #     ind.fitness.values = fit
    
        print("  Evaluated %i individuals" % len(pop))  # 这时候,pop的长度还是300呢
        print("  迭代 %i 次" % NGEN)
    
        t1 = time.clock()
        # Begin the evolution      开始进化了哈!!!注意注意注意!就是一个for循环里了!NGEN次--代数
        for g in range(NGEN):
            if g % 10 == 0:
                print("-- Generation %i --" % g)
    
            # Select the next generation individuals
            offspring = toolbox.select(pop, len(pop))
            # Clone the selected individuals
            offspring = list(map(toolbox.clone, offspring))
    
            # Apply crossover and mutation on the offspring
            for child1, child2 in zip(offspring[::2], offspring[1::2]):
    
                # cross two individuals with probability CXPB
                if random.random() < CXPB:
                    toolbox.mate(child1, child2)
    
                    # fitness values of the children
                    # must be recalculated later
                    del child1.fitness.values
                    del child2.fitness.values
    
            for mutant in offspring:
    
                # mutate an individual with probability MUTPB
                if random.random() < MUTPB:
                    toolbox.mutate(mutant)
                    del mutant.fitness.values
    
            # Evaluate the individuals with an invalid fitness
            invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
            fitnesses = map(toolbox.evaluate, invalid_ind)
            for ind, fit in zip(invalid_ind, fitnesses):
                ind.fitness.values = fit
    
            # print("  Evaluated %i individuals" % len(invalid_ind))
    
            # The population is entirely replaced by the offspring
            pop[:] = offspring
    
            # Gather all the fitnesses in one list and print the stats
            fits = [ind.fitness.values[0] for ind in pop]
    
            length = len(pop)
            mean = sum(fits) / length
            sum2 = sum(x * x for x in fits)
            std = abs(sum2 / length - mean ** 2) ** 0.5
    
            # print("  Min %s" % min(fits))
            # print("  Max %s" % max(fits))
            # print("  Avg %s" % mean)
            # print("  Std %s" % std)
    
        print("-- End of (successful) evolution --")
    
        best_ind = tools.selBest(pop, 1)[0]
        print("Best individual is %s, %s" % (best_ind, best_ind.fitness.values))
    
        print('预测数据')
        # PevalOneMax([0.6222847026584997, 0.9952779203368345, 0.10901692485431957, 0.8966275594961192, 0.9692993203252058])
        print('该次遗传算法的出的最好的参数的通过数:')
        PevalOneMax(best_ind)
    
        print('出题方给的定价规律的预测通过数',TevalOneMax())
        t2 = time.clock()
        print(t2 - t1)
    
    if __name__ == "__main__":
        # t1 = time.clock()
        main()
        # t2 = time.clock()
        # print(t2-t1)
    

    下载数据文件

    链接: https://pan.baidu.com/s/1gfcTzpx 密码: dibq

  • 相关阅读:
    WebCollector2.7爬虫框架——在Eclipse项目中配置
    JavaScript 输出
    CSS3 页面中展示邮箱列表点击弹出发送邮件界面
    CSS3 Flex Box(弹性盒子)
    CSS 分页实例
    CSS 图片
    CSS3 用户界面
    CSS3 动画
    CSS3 过渡
    CSS3 3D转换
  • 原文地址:https://www.cnblogs.com/fonttian/p/9162765.html
Copyright © 2011-2022 走看看