⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cherrymoya.cpp

📁 此代码经过大量使用
💻 CPP
字号:
/***************************************************************************                          cherrymoya.cpp  -  description                             -------------------    begin                : Sat Jan 19 2002    copyright            : (C) 2002 by Rudiger Koch    email                : rkoch@rkoch.org ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#include "cherrymoya.h"#include "fastneuron.h"#include "layer.h"#include <cmath>#include <iostream>Cherrymoya::Cherrymoya(unsigned int r){    radius = r;    dendriteRadius = 1.;    stepSize = 0.2;    offset = 0.4;    axonLengthFactor = 4;    N_chromosome = 0;    net = new Network;    layerConst.learningConst = 1e-3;     // was: 1e-3    layerConst.membraneTimeConst = 10.0;  // was: 10.0    layerConst.synapticTimeConst = 2.0;  // was: 2.0    layerConst.restPtnl = 0.0;           // was: 0.0    layerConst.thresholdPtnl = 5.0;  // was: 5.0    layerConst.type = INPUTLAYER;    layerConst.layerId = 1;    inputLayer = new Layer();    inputLayer->SetLayerConstants(layerConst);    inputLayer->LayerName("InputLayer");    layerConst.type = HIDDENLAYER;    layerConst.layerId = 2;    hiddenLayer = new Layer();    hiddenLayer->SetLayerConstants(layerConst);    hiddenLayer->LayerName("TheSkinAndTheMeat");    layerConst.type = OUTPUTLAYER;    layerConst.layerId = 3;    outputLayer = new Layer();    outputLayer->SetLayerConstants(layerConst);    outputLayer->LayerName("OutputLayer");    nId = 1;    BuildCherrymoya();    synapses = 0;}Cherrymoya::~Cherrymoya(){}void Cherrymoya::startChromosome(int geneLength, int genes){    N_chromosome++;    if(N_chromosome > 3 ) throw  string("unknown chromosome");    N_gene = 0;}void Cherrymoya::gene(string gene){    unsigned char uc;    N_gene++;    float phi = gene[0] * M_PI / 128.;    float theta = gene[1] * M_PI / 128.;    float strength;    float r;    switch(N_chromosome) {        case SKIN:            strength = gene[2] / 128.;   // between -1 and +1            r = radius + offset;            break;        case OUT:            uc = gene[3];            strength = - float(unsigned(uc)) / 256.;   // pours at input neurons            r = gene[2] / 128. * (radius + offset - 1);            break;        case IN:            uc = gene[3];            strength = float(unsigned(uc)) / 256.;        // sinks at output neurons            r = gene[2] / 128. * (radius + offset - 1);            break;        default:            throw  string("unknown chromosome");    }    float x = cos(phi) * sin(theta) * r;    float y = sin(phi) * sin(theta) * r;    float z = cos(theta) * r;    pair < float, Neuron*> singularity;    Neuron *tmpNeuron;    if(N_chromosome != SKIN) {  // The skin singularities don't go with I/O neurons        tmpNeuron = new FastNeuron(nId++);        tmpNeuron->SetLearningConst(layerConst.learningConst);        tmpNeuron->SetTimeConstants(layerConst.synapticTimeConst,                                    layerConst.membraneTimeConst);        tmpNeuron->SetRestPotential(layerConst.restPtnl);        tmpNeuron->SetThresholdPotential(layerConst.thresholdPtnl);        float location [3];        location [0] = x;        location [1] = y;        location [2] = z;        PhysicalProperties *props = tmpNeuron->GetPhysicalProperties();        props->SetLocation(location);        singularity.first = strength;        singularity.second = tmpNeuron;    }    float *skinSingularity;    switch(N_chromosome) {        case SKIN:            skinSingularity = new float[3];            skinSingularity[0] = strength;            skinSingularity[1] = phi;            skinSingularity[2] = theta;            skinSingularities.push_back(skinSingularity);            break;        case IN:            inputLayer->AddNeuron(tmpNeuron);            inputNeurons.push_back(singularity);            break;        case OUT:            outputLayer->AddNeuron(tmpNeuron);            outputNeurons.push_back(singularity);            break;        default:            break;    }}const int& Cherrymoya::getradius(){    return radius;}void Cherrymoya::BuildCherrymoya(){  // We buildup the sphere by traversing each block of the qube around the  // sphere. If a block is within the radius, a skin neuron is placed there.  // If a block is within r = radius-1 a meat neuron is placed    const float outerRadius = radius + offset;    const float innerRadius = radius + offset - 1;    for (int x = -radius; x <= radius; x++){        vector < vector <pair <bool, Neuron * > > > yVector;        theCherrymoya.push_back(yVector);        for (int y = -radius; y <= radius; y++){            vector <pair <bool, Neuron * > > zVector;            theCherrymoya[x+radius].push_back(zVector);            for (int z = -radius; z <= radius; z++){                float neuronRadius = sqrt(float(x*x + y*y + z*z));                if(neuronRadius < outerRadius){                    Neuron *tmpNeuron = new FastNeuron(nId++);                    tmpNeuron->SetLearningConst(layerConst.learningConst);                    tmpNeuron->SetTimeConstants(layerConst.synapticTimeConst,                                                layerConst.membraneTimeConst);                    tmpNeuron->SetRestPotential(layerConst.restPtnl);                    tmpNeuron->SetThresholdPotential(layerConst.thresholdPtnl);                    hiddenLayer->AddNeuron(tmpNeuron);                    float location [] = {(float)x, (float)y, (float)z };                    PhysicalProperties *props = tmpNeuron->GetPhysicalProperties();                    props->SetLocation(location);                    if(neuronRadius > innerRadius){  // skin neuron                         pair<bool, Neuron*> n(true, tmpNeuron);                         theCherrymoya[x+radius][y+radius].push_back(n);                    } else {                         // meat neuron                         pair<bool, Neuron*> n(false, tmpNeuron);                         theCherrymoya[x+radius][y+radius].push_back(n);                    }                } else {                    pair<bool, Neuron*> n = pair<bool, Neuron*>(true, NULL);                    theCherrymoya[x+radius][y+radius].push_back(n);                }            }        }    }}void Cherrymoya::finish(){    net->AddLayer(inputLayer);    net->AddLayer(outputLayer);    net->AddLayer(hiddenLayer);    connectSkin();    connectMeat();    connectInputNeurons();    cout << "Network generated: " << nId << " neurons, " << synapses << " synapses" << endl;}Network* Cherrymoya::getNetwork(){    return net;}void Cherrymoya::connectSkin(){    for (int x = -radius; x <= radius; x++){        for (int y = -radius; y <= radius; y++){            for (int z = -radius; z <= radius; z++){                if(theCherrymoya[x+radius][y+radius][z+radius].second == NULL) continue;                if(theCherrymoya[x+radius][y+radius][z+radius].first  == false) continue;                AxonConnectorSkin(theCherrymoya[x+radius][y+radius][z+radius].second);            }        }    }}void Cherrymoya::connectMeat(){    for (int x = -radius; x <= radius; x++){        for (int y = -radius; y <= radius; y++){            for (int z = -radius; z <= radius; z++){                if(theCherrymoya[x+radius][y+radius][z+radius].second == NULL) continue;                if(theCherrymoya[x+radius][y+radius][z+radius].first  == true) continue;                AxonConnector3D(theCherrymoya[x+radius][y+radius][z+radius].second);            }        }    }}void Cherrymoya::connectInputNeurons(){    for(unsigned int i=0; i<inputNeurons.size(); i++){        AxonConnector3D(inputNeurons[i].second);    }}void Cherrymoya::getFieldStrengthMeat(float *location, float *E){    E[0] = 0.;    E[1] = 0.;    E[2] = 0.;    for(unsigned int i=0; i<outputNeurons.size(); i++){        PhysicalProperties *props = outputNeurons[i].second->GetPhysicalProperties();        float nLoc[3];        props->GetLocation(nLoc);        float r[3];        for (unsigned int j=0; j<3; j++) r[j] = location[j] - nLoc[j];        float div = r[0]*r[0] + r[1]*r[1] + r[2]*r[2];        if(div < 0.3) div = 0.2;        float constants = outputNeurons[i].first / div;        for (unsigned int j=0; j<3; j++) E[j] += constants * r[j];    }    for(unsigned int i=0; i<inputNeurons.size(); i++){        PhysicalProperties *props = inputNeurons[i].second->GetPhysicalProperties();        float nLoc[3];        props->GetLocation(nLoc);        float r[3];        for (unsigned int j=0; j<3; j++) r[j] = location[j] - nLoc[j];        float div = r[0]*r[0] + r[1]*r[1] + r[2]*r[2];        if(div < 0.3) div = 0.2;        float constants = inputNeurons[i].first / div;        for (unsigned int j=0; j<3; j++) E[j] += constants * r[j];    }    for (unsigned int i=0; i<3; i++) {   // make sure E doesn't get too big close to a singularity        if(E[i] > radius) E[i] = radius;        if(E[i] < -radius) E[i] = -radius;    }}// FIXME: The whole function is junk (both it's semantics and it's implementation)void Cherrymoya::AxonConnector3D(Neuron *currentNeuron){    float axonTraverser[3], E[3];    float weight;    float ourLoc[3];    currentNeuron->GetPhysicalProperties()->GetLocation(ourLoc);    for(int i=0; i<3;i++)axonTraverser[i] = ourLoc[i];    vector < unsigned int > axon;      // remember who we already connected to    unsigned int ourId = currentNeuron->GetID();    axon.push_back(ourId);    // and make sure we don't connect to ourselves    getFieldStrengthMeat(axonTraverser, E);    const float axonLength = axonLengthFactor * sqrt(E[0]*E[0] + E[1]*E[1] + E[2]*E[2]);    float axonPos = 0; // current position on the axon in axon coordinates    while(axonPos < axonLength){        Neuron *postN;        float direction[3];        getFieldStrengthMeat(axonTraverser, direction);        float length = sqrt(direction[0] * direction[0] +                            direction[1] * direction[1] +                            direction[2] * direction[2]);        axonPos += stepSize;        if(axonPos > dendriteRadius) weight = 0.5;  // FIXME: AD HOC!!!!        else weight = -0.5;        for(int i=0; i<3;i++) axonTraverser[i] += direction[i] * stepSize / length;        // is there an output neuron?        for(unsigned int i=0; i<outputNeurons.size(); i++){            PhysicalProperties *props = outputNeurons[i].second->GetPhysicalProperties();            float nLoc[3];            props->GetLocation(nLoc);            float distance = sqrt((axonTraverser[0] - nLoc[0]) * (axonTraverser[0] - nLoc[0]) +                                  (axonTraverser[1] - nLoc[1]) * (axonTraverser[1] - nLoc[1]) +                                  (axonTraverser[2] - nLoc[2]) * (axonTraverser[2] - nLoc[2]));            if(distance < dendriteRadius) {                for(unsigned int j=0; j<axon.size(); j++){                    if(axon[j] == outputNeurons[i].second->GetID()) goto FIXME1; // already connected                }                axon.push_back(outputNeurons[i].second->GetID());                net->ConnectNeurons(ourId, outputNeurons[i].second->GetID(), weight); // FIXME: variabe weights                synapses++;            }        }FIXME1:        for (int x = -radius; x <= radius; x++){            for (int y = -radius; y <= radius; y++){                for (int z = -radius; z <= radius; z++){                    if(theCherrymoya[x+radius][y+radius][z+radius].second == NULL) continue;                    float distance = sqrt((x - axonTraverser[0]) * (x - axonTraverser[0]) +                                          (y - axonTraverser[1]) * (y - axonTraverser[1]) +                                          (z - axonTraverser[2]) * (z - axonTraverser[2]));                    if(distance < dendriteRadius) {                        postN = theCherrymoya[x+radius][y+radius][z+radius].second;                        if(postN != NULL) {                            for(unsigned int i=0; i<axon.size(); i++){                                if(axon[i] == postN->GetID()) goto FIXME;  // already connected                            }                            synapses++;                            net->ConnectNeurons(ourId, postN->GetID(), weight); // FIXME: variabe weights                            axon.push_back(postN->GetID());                        }                    }                }            }        }FIXME:   continue;         // no comment on this - this function MUST be re-implemented    }}void Cherrymoya::getFieldStrengthSkin(float *location, float *E){    E[0] = 0.;    E[1] = 0.;    // Bronstein S.217    const float phi_n   = atan(location[1] / location[0]);    const float theta_n = atan(sqrt(location[1]*location[1] + location[0]*location[0]) / location[2]);    for(unsigned int i=0; i<skinSingularities.size(); i++){        const float strenght = skinSingularities[i][0];        const float phi_s    = skinSingularities[i][1];        const float theta_s  = skinSingularities[i][2];        // calculate the distance according to Bronstein, 3.197 (S.172)        const float distance = radius * acos(sin(phi_n)*sin(phi_s) + cos(phi_n)*cos(phi_s)*cos(theta_s - theta_n));// TODO: do the rest of the calculation    }}void Cherrymoya::AxonConnectorSkin(Neuron *currentNeuron){    float ourLoc[3];    float shadowLoc[3];    currentNeuron->GetPhysicalProperties()->GetLocation(ourLoc);    // Bronstein S.217 - 3.355a    const float phi   = atan(ourLoc[1] / ourLoc[0]);    const float theta = atan(sqrt(ourLoc[1]*ourLoc[1] + ourLoc[0]*ourLoc[0]) / ourLoc[2]);    shadowLoc[0] = sin(theta)*cos(phi)*radius / 4.;    shadowLoc[1] = sin(theta)*sin(phi)*radius / 4.;    shadowLoc[2] = cos(theta)*radius / 4.;    currentNeuron->GetPhysicalProperties()->SetLocation(shadowLoc);    AxonConnector3D(currentNeuron);    currentNeuron->GetPhysicalProperties()->SetLocation(ourLoc);}vector <AmIdInt> Cherrymoya::GetInputNeurons(){    vector <AmIdInt> iNeurons;    for (unsigned int i=0; i<inputNeurons.size(); i++){        iNeurons.push_back(inputNeurons[i].second->GetID());    }    return iNeurons;}vector <Neuron*> Cherrymoya::GetOutputNeurons(){    vector <Neuron*> oNeurons;    for (unsigned int i=0; i<outputNeurons.size(); i++){        oNeurons.push_back(outputNeurons[i].second);    }    return oNeurons;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -