进化计算学习笔记(2)

本文介绍了如何使用Python实现遗传算法,并给出了基于PlatEMO框架的简化代码示例,包括种群初始化、交叉、变异等操作。代码中使用了CUPY加速计算,同时讨论了科研中的创新挑战和现状,强调了保持梦想和探索精神的重要性。
摘要由CSDN通过智能技术生成

过了半年多了,现在也到下学期,想起来还有这个事,就来填填坑
话不多说,直接上一个遗传算法的python代码(根据老师的PlatEMO框架里面的GA代码复现,具体matlab代码请看PlatEMO
我这里用到了cupy,CUPY相当于是numpy的升级版,会加快两个ndarray之间的运算,具体用法请看官方文档,本质上与numpy不尽相同,就只有一些数据类型上不一样。

from math import floor
import cupy as cp
import time

class GA:
    def __init__(self,population,epochs):  # 输入许多个体即种群
        self.population = population
        self.epochs = epochs

    def solve(self):
        rank = []
        idx = 0
        for i in range(self.epochs):
            matingPool = self.TournamentSelection(2,self.population.objs())
            print("--------------第{}代交配池---------------".format(i+1))
            print(matingPool)
            pop = []
            for j in matingPool:
                pop.append(self.population.idvs[j])
            offSpring = self.operator(pop)
            popu = self.population.idvs + offSpring
            rank.append(self.sort(popu))
            self.population.idvs = rank[idx]
            idx += 1
            print("第{}代最优网络的loss为{:.4f}".format(i+1,self.population.idvs[0].obj))
        return rank

    def sort(self,pop):
        res = []
        while len(res)<self.population.num:
            min = 100000000
            idx = 0
            for j in range(len(pop)):
                if pop[j].obj<min:
                    min = pop[j].obj
                    idx = j
            res.append(pop[idx])
            pop.remove(pop[idx])
        return res

    def TournamentSelection(self,K,objs):   # k元联赛选择算法,返回最佳的下标数组
        l = objs[:]
        l.sort()
        p = [[np.random.randint(0,len(l)).tolist() for m in range(K)] for n in range(len(l))]
        best = []
        for i in p:
            min = i[0]
            for j in i:
                if j==min:
                    continue
                if l[j] < l[min]:
                    min = j
            best.append(min)
        return best

    def operator(self,pop):
        a = time.time()
        p1 = pop[0:floor(len(pop)/2)]
        p2 = pop[floor(len(pop)/2):floor(len(pop)/2)*2]
        for i in range(len(p1)):
            if p1[i]==p2[i]:
                continue
            if np.random.rand()<0.6:	# 交叉率0.6
                k = np.random.permutation(len(p1[0].w))[:floor(len(p1[0].w)*0.6)]
                t1 = p1[i]
                t2 = p2[i]
                t1.w[k],t2.w[k] = t2.w[k].copy(),t1.w[k].copy()
                p1[i],p2[i] = t1.copy(),t2.copy()
        b = time.time()
        print("CrossUseTime:{:.2f}s".format(b-a))
        off = p1+p2
        for i in range(len(off)):
            if np.random.rand()<0.2:	# 变异率0.2
                # print("BeforMute obj:{:.4f}".format(off[i].obj))
                m = np.random.permutation(len(off[0].w))[:floor(len(off[0].w)*0.02)]
                tmp = off[i]
                tmp.w[m] = -tmp.w[m].copy()
                off[i] = tmp.copy()
                # print("AfterMute obj:{:.4f}".format(off[i].obj))
        print("MuteUseTime:{:.2f}s".format(time.time()-b))
        return off

我这里用的交叉是模拟二进制交叉SBX,变异的话是针对二值(-1,1)做的。整个代码较为简单,没有PlatEMO里面写的那么全。

什么?你问我Population和Individual怎么写的?

这个要根据具体问题来写了,算法毕竟是基本上没有什么变化的,变的只有数据。
那我给一个简单的Population和Individual的代码

Population

from Individual import Individual
class population:
    def __init__(self,N):
        self.num = N
        self.idvs = []
        for i in range(N):
        	x = 随机生成的参数
        	idv = Individual()
        	self.idvs.append(idv)
	        print('个体{}的目标值为:{:.4f}'.format(i,idv.obj))
	        
    def objs(self):
        res = []
        for i in self.idvs:
            res.append(i.obj)
        return res

Individual

import cupy as cp

def LossF(**args):
	obj = args[0]+args[1]+...
    return obj

class Individual:
    def __init__(self,**args):
        self.x = args
        self.obj = LossF(self.x)

    def copy(self):
        new = Individual(self.x)
        return new

应该还算好理解吧,我简化了很多复杂的结构,直接把最本质的框架提取出来。

题外话:

虽然到目前为止看了数十篇论文了,但还是没什么创新的想法,感觉能想到的都有人做过了,别人没做过的也想不到。现在搞科研真的是越来越难了,如果不开发新领域的话真的就无法脱出内卷的大坑了。
说句实话,计算机方向所剩的能开发的领域越来越少,越晚读研越难创新,甚至发论文毕业都是问题。每年数十万研究生毕业,每年都有数十万篇论文要发表,越晚入局就意味着越难出成果。
不过嘛,人一定要有梦想,毕竟没有梦想支撑的生活就是一片空白,只会越活越乏味。说不定哪天能突发奇想,思路来了呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值