学生作业演化算法

机器学习演化算法学生作业

import sympy as sy
import random          # y = (xi)^2 变异重组 利用偏导数的值 寻找最小值
import copy


def bianma(upper_bound, lower_bound, geshu, nwei):

    p = []
    pey = {}
    while len(p) < geshu:           # 生成随意geshu个长度为nwei的不相同二进制编码
        t = ""

        for i in range(nwei):
            q = str(random.randint(0, 1))
            t = t + q
        if t not in p:
            p.append(t)

    for i in p:  # 将编码分配到函数可行域,得到数学对应值。
        ey = (upper_bound - lower_bound) * (int(i, 2)) / 2 ** nwei + lower_bound
        pey[i] = ey

    return p, pey


def bianliangbiao(d):
    s = []
    for i in range(d):
        t = "x" + str(i + 1)

        s.append(t)
    return s


def jiema(jieji, upper_bound, lower_bound):
    pey = {}
    for i in jieji:
        ey = (upper_bound - lower_bound) * (int(i, 2)) / 2 ** len(i) + lower_bound
        pey[i] = ey
    return pey


def evaluate(eva_ls, shu_ma, d):
    r = {}      # xi与编码
    q = {}      # xi与编码数学值
    qi = {}     # {编码:偏导值}
    chuji = copy.copy(eva_ls)
    f = 0
    e = 0
    bianliang = bianliangbiao(d)                    # 输入d,生成bianliang['x1','x2'.....'xd']
    for i in bianliang:
        r[i] = random.choice(chuji)                 # ,r->{'xi':'码'}
        chuji.remove(r[i])

    for i in r:
        i = sy.symbols(str(i))  # 将xd赋为变量
        f = f + i * i
    '''

               F1
                  for i in r:
               i = sy.symbols(str(i))                      # 将xd赋为变量
               f = f+i*i                                   # 测试函数
               F2
               xi_index=bianliang.index(i)
               i = sy.symbols(str(i))                      # 将xd赋为变量
               f = f+(xi_index+1)*i*i                      # 测试函数
               F3
               i = sy.symbols(str(i))  # 将xd赋为变量
               f = f + abs(i+0.5) **2  # 测试函数
               F4
               xi_index = bianliang.index(i)
               i = sy.symbols(str(i))  # 将xd赋为变量
               f = f + (xi_index + 1) * i ** 4 + random.randint(0, 1)'''

    for i in r:
        w = sy.diff(f, i)                           # 求得偏导 e(xd)
        e += w
        q[i] = shu_ma[r[i]]                        # 将xd 与 对应编码的数学值 归入字典{q}
        t = w.subs({i: q[i]})                      # 求各个Xi偏导值t
        qi[r[i]] = abs(t)                          # qi {码:偏导值},ls[码]

    return eva_ls, qi


def mutation(p, muji):

    mo = []
    pp = copy.copy(muji)                # 变异,遍历群体 , 遍历个体, 每个个体编码的每个位置都有p的概率变异。
    len_muji = len(pp)
    for i in muji:
        q = ""
        for t in i:
            pt = random.randint(1, 100)
            if p >= pt:
                t = abs(int(t)-1)
                q = q + str(t)
            else:
                q = q + t
        if q not in mo:                 # 避免mo 内元素重复,当mo内不含有q时,增加q
            mo.append(q)
        else:
            continue
    while len(mo) != len_muji:         # 补齐子集群体个数 ,不够的时候 ,从母群体挑选补到子集。
        for o in pp:
            if o not in mo:
                mo.append(o)
                break
    muji = copy.copy(mo)
    return muji


def crossover(pc, coji):

    yuanji = copy.copy(coji)
    e = copy.copy(coji)
    mi = []
    t = len(yuanji)
    d = yuanji
    while len(d) > 2:
        pt = random.randint(1, 100)
        c = random.randint(0, len(d) - 1)
        cy = d[c]
        d.pop(c)
        b = random.randint(0, len(d) - 1)
        by = d[b]
        d.pop(b)
        if pc >= pt:
            q = random.randint(0, len(d[0]))
            cyy = cy.replace(cy[q:-1], by[q:-1])
            byy = by.replace(by[q:-1], cy[q:-1])
            mi.append(cyy)
            mi.append(byy)
        else:
            mi.append(cy)
            mi.append(by)

    for i in d:
        mi.append(i)
    mi = list(set(mi))
    while len(mi) != t:                 # 避免mi元素重复,转元组再转列表 至mi元素补齐。
        for o in e:
            if o not in mi:
                mi.append(o)
                break
    coji = copy.copy(mi)
    return coji


def select(c1, c2):

    c = {}
    v_dict = {}
    v_ls = []
    c.update(c1)
    c.update(c2)
    c_order = sorted(c.items(), key=lambda x: x[1], reverse=False)

    for i in range(len(c1)):
        v_dict[c_order[i][0]] = c_order[i][1]
        v_ls.append(c_order[i][0])

    return v_ls, v_dict


a = bianma(100, -100, 40, 50)    # bianma(上界,下界,编码个数,编码长度)
b = evaluate(a[0], a[1], 30)     # 输入[评估群体],{群体:数值},维度 ;;; 输出:b[0]->[初码], b[1]->{初码 :偏导值}
poi = sum(b[1].values())         # 偏导值的和
i = 0
while poi > 0.01:
    i += 1
    mu = mutation(5, b[0])                 # 变异,p 取值为【0~100】
    co = crossover(20, mu)                  # 交叉,p 取值【0~100】
    co_number = jiema(co, 100, -100)        # 解码,输入[码集],输出{码:数学值}
    ne = evaluate(co, co_number, 30)        # 评估,输入[码],{码:数} 维度  输出[码] {码:偏导值}    ne[0]->码 ,ne[1]->码与偏导
    new = select(b[1], ne[1])               # 挑选,b[1] ne[1] 的并集的前一半。输出new ([码],{码:偏导值})
    poi = sum(new[1].values())              # 新集群偏导值
    b = new                                 # b = 新集群
    print(poi)
else:
    print(poi)                              # 输出[偏导值]
    print(i, sum(jiema(b[0], 100, -100).values()), jiema(b[0], 100, -100).values())  # 输出数学值











评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值