Esempio n. 1
0
    def __init__(self, range):
        '''
        值范围
        :param range: str,格式如[0:1] (0:1) [0:1:0.1] (0:1:0.1) uniform[0:1] normal[0,1],其中[]与()为数值区间
        '''
        self.rangeStr = range

        self.distributionName = 'uniform'
        self.begin = 0
        self.includeBegin = True
        self.end = 1
        self.IncludeEnd = True
        self.step = 0.1
        self.__list = []
        self.__stepMode = 'step'

        #m = re.compile('(\S*)').match('uniform')
        #m = re.compile('(\[|\(){1}').match('[')
        #m = re.compile('((\+|-)?\d+(\.\d+)?){1}').match('-30.0')
        #m = re.compile('\:').match(':')
        #m = re.compile('(\:(\+|-)?\d+(\.\d+)?)?').match(':-30.0')
        #m = re.compile('(\]|\)){1}').match(']')

        if not strs.isVaild(range): return
        m = Range.pattern.match(range)
        self.distributionName = m.groups()[0]
        self.begin = float(m.groups()[2])
        self.end = float(m.groups()[5])
        self.step = (self.end -
                     self.begin) / 10 if m.groups()[9] is None else float(
                         m.groups()[9])  #?有错误
Esempio n. 2
0
 def __repr__(self):
     '''
     用于调试打印详细信息
     :return:
     '''
     return self.name + '' if not strs.isVaild(
         self.description) else '(' + self.description + ')'
Esempio n. 3
0
def getFullDirectory(dir):
    '''
    得到全路径,并以/结尾
    :param dir:
    :return:
    '''
    if (os.path.exists(dir)): return dir
    if not strs.isVaild(dir): return dir
    if dir.startWith('/') or dir.contains(':'): return dir
    p = os.path.dirname(os.path.abspath(__file__) + dir)
    if not p.endswith('/'): p += '/'
Esempio n. 4
0
 def register(self, obj, name=''):
     '''
     注册
     :param obj:  注册对象
     :param name: 对象名称,如果无效,则尝试调用strs.getName(obj)取得
     :return: None
     '''
     if obj is None: return
     if name == '': name = strs.getName(obj)
     if not strs.isVaild(name): return
     self.__tables__[name] = obj
Esempio n. 5
0
def getFullFileName(filename, dir=''):
    '''
    取得全文件名
    :param filename: 如果文件名是全路径,则结果不变,否则以py所在路径+dir为文件所在路径
    :param dir:
    :return:
    '''
    # 如果文件存在,仍返回文件名
    if (os.path.exists(filename)): return filename
    # 如果文件名包含全路径,直接返回文件名(windows操作系统中是包含:,unix家族是/开始)
    if not strs.isVaild(filename): return filename
    if filename.startWith('/') or filename.contains(':'): return filename

    p = os.path.dirname(os.path.abspath(__file__) + dir)
    if not p.endswith('/'): p += '/'
    return p + filename
Esempio n. 6
0
    def find(self, name, default=None, setifnotexist=True):
        '''
        查找对象
        :param name:           str 对象名称
        :param default:        any 缺省对象
        :param setifnotexist:  如果找不到,是否将default记录(下次就可以找到)
        :return: 注册的对象
        '''
        if not strs.isVaild(name): return default
        #if name in self.__tables__.keys():
        if name in self.__tables__:
            return self.__tables__[name]

        if not setifnotexist: return default
        self.__tables__[name] = default
        return default
Esempio n. 7
0
    def _initModel(self):
        '''
        初始化计算模型:找到注册的计算模型,根据模型中的状态信息初始化神经系统元素状态,
        并将计算模型中登记的变量克隆一份在元素对象中(计算模型中本身的变量只是模版,并不在实际计算中使用,这样可以使得计算模型成为单体对象)
        :return:
        '''

        # 根据模型配置取得模型对象
        if self.modelConfiguration is None: raise RuntimeError('初始化计算模型失败(NueralElement.initModel):模型配置无效')
        if len(self.modelConfiguration)<=0:return
        if not strs.isVaild(self.modelConfiguration.modelid): raise RuntimeError('初始化计算模型失败(NueralElement.initModel):模型配置中modelId无效')
        model = models.nervousModels.find(self.modelConfiguration.modelid)
        if model is None:raise RuntimeError('初始化计算模型失败(NueralElement.initModel):找不到模型:'+self.modelConfiguration.modelid)
        # 如果模型规定了要有初始状态,则设置初始状态
        self.states = {} if model.initStates is None else copy.deepcopy(model.initStates)

        # 拷贝模型中规定的所有变量,并初始号变量的值
        self.variables = [var.clone() for var in model.variables]
        self._initVariableValue()
Esempio n. 8
0
 def __repr__(self):
     #stateStr = collections.dicttostr(self.states)
     varStr = collections.listtostr(list(map(lambda v: v.__repr__(), self.variables)))
     return 'Synapse' + str(self.id) + '[' + str(self.fromId) + '->' + str(self.toId) \
            + (',' + varStr if strs.isVaild(varStr) else '') + ']'
Esempio n. 9
0
 def __str__(self):
     varStr = collections.listtostr(list(map(lambda v: v.__repr__(), self.variables)))
     varStr = '[' + varStr + "]" if strs.isVaild(varStr) else ''
     return 'Synapse'+str(self.id)+'('+str(self.fromId)+'->'+str(self.toId)+')' + varStr
Esempio n. 10
0
 def __str__(self):
     #stateStr = collections.dicttostr(self.states)
     varStr = collections.listtostr(list(map(lambda v:v.__repr__(),self.variables)))
     return 'Neuron'+str(self.id)+'[layer='+str(self.layer) \
            + (',' + varStr if strs.isVaild(varStr) else '') + ']'
Esempio n. 11
0
 def _getFeatureStr(self):
     r = collections.dicttostr(self.features)
     return '(' + r + ')' if strs.isVaild(r) else ''
Esempio n. 12
0
    def execute(self,session):
        # 执行算法选择个体
        sel_inds = self.select(session)

        # 将要函数的个体删除
        individuals = session.pop.inds
        totalSize = len(individuals)
        removeInds = [ind for ind in individuals if ind not in sel_inds]
        removeIndids = [ind.id for ind in individuals if ind not in sel_inds]
        removeInd_count = len(removeInds)
        session.monitor.recordDebug(NSGA2.name, '删除的个体',
                                    collections.mapreduce(removeIndids, reducefunc=lambda i, j: str(i) + ',' + str(j)))
        for removeInd in removeInds:
            session.pop.removeInd(removeInd)
        individuals = session.pop.inds

        # 对剩余的个体按照分别按照不同的适应度函数排序
        sortedinds = {}
        for eva,i in enumerate(session.popParam.features):
            sortedinds[eva.key] = sorted(individuals,key=lambda x: x[eva.key] + 0.000001)
        featurekeys = [key for key,eva in session.popParam.features.items()]

        # 选择待交叉的个体
        corssmeateInds = []
        keyIndex = 0
        for i in range(removeInd_count):
            if len(individuals) == 1:
                corssmeateInds.append((individuals[0], individuals[0]))
            elif len(individuals) == 2:
                corssmeateInds.append((individuals[0], individuals[1]))
            else:
                indspar = self.roulette(individuals,2,featurekeys[keyIndex])
                keyIndex = 0 if keyIndex>=len(featurekeys)-1 else keyIndex + 1
                corssmeateInds.append(indspar[0],indspar[1])
        sdebug = ''
        for cross in corssmeateInds:
            if strs.isVaild(sdebug): sdebug += ','
            sdebug += str(cross[0]) + '-' + str(cross[1])
        session.monitor.recordDebug(NSGA2.name, '交叉的个体', sdebug)

        # region 第四步:对所有个体按照适应度从高到低排序,随机选择其中一部分作为变异个体
        metateinds = []
        # 计算变异个体数量
        mutateCount = int(session.runParam.mutate.propotion) if session.runParam.mutate.propotion >= 1 else int(
            totalSize * session.runParam.mutate.propotion)
        if mutateCount <= 0:
            return True, '', (corssmeateInds, metateinds)

        # 对所有个体按照适应度从高到低排序
        session.pop.inds.sort(key=lambda x: x['fitness'] + 0.000001 if x in session.pop.eliest else 0, reverse=True)
        # 选择候选变异个体(精英个体将被排除)
        candidateInds = collections.findall(session.pop.inds, lambda ind: ind not in session.pop.eliest)
        # 为每个个体计算一个选择概率(适应度越低的被选择的概率就高)
        if len(candidateInds) <= 0:
            max, avg, min, stdev = 0., 0., 0., 0.
            print('变异个体数量无效,' + str(session.pop.eliest))
            return True, '选择操作完成,其中淘汰个体数量=' + str(len(removeIndids)) + ',交叉个体数量=' + str(
                len(corssmeateInds)) + ',变异个体数量=0', (
                       corssmeateInds, [])

        else:
            max, avg, min, stdev = collections.rangefeature(list(map(lambda ind: ind['fitness'], candidateInds)))
        # fitnesssum = sum(list(map(lambda ind:ind['fitness'],candidateInds)))
        mutateSelProb = [1 - ((ind['fitness'] - min) / ((max - min) if max != min else 1)) for index, ind in
                         enumerate(candidateInds)]
        mutateSelProb = np.array(mutateSelProb)
        p = mutateSelProb / mutateSelProb.sum()
        np.random.seed(0)
        # p = np.array(mutateSelProb)
        mutateinds = np.random.choice(candidateInds, size=mutateCount, p=p.ravel())
        session.monitor.recordDebug(NSGA2.name, '变异的个体',
                                    reduce(lambda i, j: i + ',' + j, map(lambda ind: str(ind.id), mutateinds)))

        return True, '选择操作完成,其中淘汰个体数量=' + str(len(removeIndids)) + ',交叉个体数量=' + str(
            len(corssmeateInds)) + ',变异个体数量=' + str(len(mutateinds)), (
               corssmeateInds, list(map(lambda ind: ind.id, mutateinds)))
Esempio n. 13
0
    def execute(self, session):
        #region 第一步:规划每个物种中应有的个体数量
        # 取得物种集合,并按平均适应度排序
        species = session.pop.getSpecies()
        if collections.isEmpty(species):
            raise RuntimeError('NEAT选择操作失败:物种集合为空')
        species.sort(key=lambda s: s['fitness']['average'], reverse=True)

        # 根据物种的平均适应度在所有物种中占的比重,计算每个物种的目标个体数量
        specie_total_fitness = sum(
            list(map(lambda sp: sp['fitness']['average'], species)))

        totalSize = 0
        for i in range(len(species)):
            specie = species[i]
            # 根据物种适应度计算目标个体数量
            speicesFitness = specie['fitness']['average']
            specie.targetSize = int((speicesFitness / specie_total_fitness) *
                                    len(session.pop.inds))
            totalSize += specie.targetSize

        # 如果所有物种的目标个体数量之和仍小于种群个体数量,将不足的部分加到适应度最高的物种上(按照上面计算,不会出现大于的情况)
        if totalSize < len(session.pop.inds):
            species[0].targetSize += len(session.pop.inds) - totalSize
        totalSize = len(session.pop.inds)

        session.monitor.recordDebug(
            'neat_selection', '物种的目标个体数量',
            reduce(lambda x, y: x + "," + y,
                   map(lambda s: str(s.id) + "=" + str(s.targetSize),
                       species)))

        #endregion

        #region 第二步:遍历每个物种,如果物种中实际个体数量大于前面计算的每个物种的目标个体数量,则将适应度差的个体淘汰
        removeIndids = []
        for i in range(len(species)):
            specie = species[i]
            # 将物种中个体按照适应度由高到低排序,其中精英个体尽管排前面
            specie.indids.sort(
                key=lambda indid: session.pop[indid]['fitness'] + 0.000001
                if session.pop[indid] in session.pop.eliest else 0,
                reverse=True)
            # 实际个体数量不多于目标个体数量,不需要淘汰
            if len(specie.indids) <= specie.targetSize:
                continue

            # 删除适应度最小的个体,直到实际个体数量与目标个体数量相等(这样的删除方法,有可能会导致精英个体也被删除)
            while len(specie.indids) > specie.targetSize:
                removeIndid = specie.indids[-1]
                removeInd = session.pop[removeIndid]
                removeIndids.append(removeIndid)
                del specie.indids[-1]  # 从物种记录中删除
                session.pop.inds.remove(removeInd)  # 从种群记录中删除
        session.monitor.recordDebug(
            'neat_selection', '删除的个体',
            collections.mapreduce(
                removeIndids, reducefunc=lambda i, j: str(i) + ',' + str(j)))

        # 遍历所有物种,如果有物种个体数量为0,则将该物种删除
        species = [s for s in species if len(s.indids) > 0]
        #endregion

        #region 第三步:对每个物种,随机选择需要交叉操作的个体
        corssmeateInds = []
        for specie in species:
            if len(specie.indids) >= specie.targetSize:
                continue
            for i in range(specie.targetSize - len(specie.indids)):
                if len(specie.indids) == 1:
                    corssmeateInds.append((specie.indids[0], specie.indids[0]))
                elif len(specie.indids) == 2:
                    corssmeateInds.append((specie.indids[0], specie.indids[1]))
                else:
                    indexpair = random.sample(range(len(specie.indids)), 2)
                    corssmeateInds.append((specie.indids[indexpair[0]],
                                           specie.indids[indexpair[1]]))

        # 有错误:session.monitor.recordDebug('neat_selection', '交叉的个体',  reduce(lambda i, j: str(list(i)[0])+"-"+str(list(i)[1]) + ',' + str(list(j)[0])+"-"+str(list(j)[1]), corssmeateInds))
        # reduce(lambda i,j:str(i[0])+'-'+str(i[1])+','+str(j[0])+'-'+str(j[1]),[(0,1),(2,3)])  --->  0-1,2-3
        # reduce(lambda i,j:str(i[0])+'-'+str(i[1])+','+str(j[0])+'-'+str(j[1]),[(0,1),(2,3),(4,5)]) ---> 0--,4-5
        sdebug = ''
        for cross in corssmeateInds:
            if strs.isVaild(sdebug): sdebug += ','
            sdebug += str(cross[0]) + '-' + str(cross[1])
        session.monitor.recordDebug('neat_selection', '交叉的个体', sdebug)

        #region 第四步:对所有个体按照适应度从高到低排序,随机选择其中一部分作为变异个体
        metateinds = []
        # 计算变异个体数量
        mutateCount = int(session.runParam.mutate.propotion
                          ) if session.runParam.mutate.propotion >= 1 else int(
                              totalSize * session.runParam.mutate.propotion)
        if mutateCount <= 0:
            return True, '', (corssmeateInds, metateinds)

        # 对所有个体按照适应度从高到低排序
        session.pop.inds.sort(key=lambda x: x['fitness'] + 0.000001
                              if x in session.pop.eliest else 0,
                              reverse=True)
        # 选择候选变异个体(精英个体将被排除)
        candidateInds = collections.findall(
            session.pop.inds, lambda ind: ind not in session.pop.eliest)
        # 为每个个体计算一个选择概率(适应度越低的被选择的概率就高)
        if len(candidateInds) <= 0:
            max, avg, min, stdev = 0., 0., 0., 0.
            print('变异个体数量无效,' + str(session.pop.eliest))
            return True, '选择操作完成,其中淘汰个体数量=' + str(
                len(removeIndids)) + ',交叉个体数量=' + str(
                    len(corssmeateInds)) + ',变异个体数量=0', (corssmeateInds, [])

        else:
            max, avg, min, stdev = collections.rangefeature(
                list(map(lambda ind: ind['fitness'], candidateInds)))
        #fitnesssum = sum(list(map(lambda ind:ind['fitness'],candidateInds)))
        mutateSelProb = [
            1 - ((ind['fitness'] - min) / ((max - min) if max != min else 1))
            for index, ind in enumerate(candidateInds)
        ]
        mutateSelProb = np.array(mutateSelProb)
        p = mutateSelProb / mutateSelProb.sum()
        np.random.seed(0)
        #p = np.array(mutateSelProb)
        mutateinds = np.random.choice(candidateInds,
                                      size=mutateCount,
                                      p=p.ravel())
        session.monitor.recordDebug(
            'neat_selection', '变异的个体',
            reduce(lambda i, j: i + ',' + j,
                   map(lambda ind: str(ind.id), mutateinds)))

        return True, '选择操作完成,其中淘汰个体数量=' + str(
            len(removeIndids)) + ',交叉个体数量=' + str(
                len(corssmeateInds)) + ',变异个体数量=' + str(len(mutateinds)), (
                    corssmeateInds, list(map(lambda ind: ind.id, mutateinds)))